home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.006 / xemacs-1 / lib / xemacs-19.13 / lisp / modes / cc-mode.el < prev    next >
Encoding:
Text File  |  1995-08-29  |  169.9 KB  |  4,755 lines

  1. ;;; cc-mode.el --- major mode for editing C, C++, and Objective-C code
  2.  
  3. ;; Copyright (C) 1985-1995 Free Software Foundation, Inc.
  4.  
  5. ;; Authors: 1992-1995 Barry A. Warsaw
  6. ;;          1987 Dave Detlefs and Stewart Clamen
  7. ;;          1985 Richard M. Stallman
  8. ;; Maintainer: cc-mode-help@merlin.cnri.reston.va.us
  9. ;; Created: a long, long, time ago. adapted from the original c-mode.el
  10. ;; Version:         4.241
  11. ;; Last Modified:   1995/08/28 16:10:40
  12. ;; Keywords: c languages oop
  13.  
  14. ;; NOTE: Read the commentary below for the right way to submit bug reports!
  15. ;; NOTE: See the accompanying texinfo manual for details on using this mode!
  16.  
  17. ;; This file is part of GNU Emacs.
  18.  
  19. ;; GNU Emacs is free software; you can redistribute it and/or modify
  20. ;; it under the terms of the GNU General Public License as published by
  21. ;; the Free Software Foundation; either version 2, or (at your option)
  22. ;; any later version.
  23.  
  24. ;; GNU Emacs is distributed in the hope that it will be useful,
  25. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27. ;; GNU General Public License for more details.
  28.  
  29. ;; You should have received a copy of the GNU General Public License
  30. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  31. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  
  33. ;;; Commentary:
  34.  
  35. ;; This package provides modes in GNU Emacs for editing C, C++, and
  36. ;; Objective-C code. It is intended to be a replacement for c-mode.el
  37. ;; (a.k.a. BOCM -- Boring Old C-Mode), and c++-mode.el (a.k.a
  38. ;; cplus-md.el and cplus-md1.el), both of which are ancestors of this
  39. ;; file.  A number of important improvements have been made, briefly:
  40. ;; complete K&R C, ANSI C, `ARM' C++, and Objective-C support with
  41. ;; consistent indentation across all modes, more intuitive indentation
  42. ;; controlling variables, compatibility across all known Emacsen, nice
  43. ;; new features, and tons of bug fixes.  This package is called
  44. ;; "cc-mode" to distinguish it from its ancestors, but there really is
  45. ;; no top-level cc-mode.  Usage and programming details are contained
  46. ;; in an accompanying texinfo manual.
  47.  
  48. ;; To submit bug reports, type "C-c C-b". Please include a code sample
  49. ;; and exact recipe so I can reproduce your problem.  If you have
  50. ;; other questions contact me at the following address:
  51. ;; cc-mode-help@merlin.cnri.reston.va.us.  Please don't send bug
  52. ;; reports to my personal account, I may not get it for a long time.
  53.  
  54. ;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
  55. ;; the multi-Emacsen support.  FSF's Emacs 19, XEmacs 19 (formerly
  56. ;; Lucid), and GNU Emacs 18 all do things differently and there's no
  57. ;; way to shut the byte-compiler up at the necessary granularity.  Let
  58. ;; me say this again: YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS (you'd
  59. ;; be surprised at how many people don't follow this advice :-).
  60.  
  61. ;; If your Emacs is dumped with c-mode.el and/or c++-mode.el, you will
  62. ;; need to add the following to your .emacs file before any other
  63. ;; reference to c-mode or c++-mode:
  64. ;;
  65. ;; (fmakunbound 'c-mode)
  66. ;; (makunbound 'c-mode-map)
  67. ;; (fmakunbound 'c++-mode)
  68. ;; (makunbound 'c++-mode-map)
  69. ;; (makunbound 'c-style-alist)
  70.  
  71. ;; There are three major mode entry points provided by this package,
  72. ;; one for editing C++ code, one for editing C code (both K&R and
  73. ;; ANSI), and one for editing Objective-C code.  To use cc-mode, add
  74. ;; the following to your .emacs file.  This assumes you will use .cc
  75. ;; or .C extensions for your C++ source, .c for your C code, and .m
  76. ;; for your Objective-C code:
  77. ;;
  78. ;; (autoload 'c++-mode  "cc-mode" "C++ Editing Mode" t)
  79. ;; (autoload 'c-mode    "cc-mode" "C Editing Mode" t)
  80. ;; (autoload 'objc-mode "cc-mode" "Objective-C Editing Mode" t)
  81. ;; (setq auto-mode-alist
  82. ;;   (append '(("\\.C$"  . c++-mode)
  83. ;;             ("\\.cc$" . c++-mode)
  84. ;;             ("\\.c$"  . c-mode)
  85. ;;             ("\\.h$"  . c-mode)
  86. ;;             ("\\.m$"  . objc-mode)
  87. ;;            ) auto-mode-alist))
  88.  
  89. ;; Several Majordomo mailing lists exist for those of you who are
  90. ;; interested in beta testing new versions: cc-mode-announce for
  91. ;; announcements of new beta versions only, and cc-mode-victims for
  92. ;; more technical discussions of the mode.  For more information, send
  93. ;; the word `help' in a message to one of the following addresses:
  94. ;;
  95. ;;       cc-mode-victims-request@merlin.cnri.reston.va.us
  96. ;;       cc-mode-announce-request@merlin.cnri.reston.va.us
  97.  
  98. ;; Many, many thanks go out to all the folks on the beta test list.
  99. ;; Without their patience, testing, insight, code contributions, and
  100. ;; encouragement cc-mode.el would be a far inferior package.
  101.  
  102. ;; Anonymous ftp URL:
  103. ;;
  104. ;;    ftp://ftp.python.org/pub/emacs/cc-mode.tar.gz
  105.  
  106. ;; LCD Archive Entry:
  107. ;; cc-mode.el|Barry A. Warsaw|cc-mode-help@merlin.cnri.reston.va.us
  108. ;; |Major mode for editing C++, Objective-C, and ANSI/K&R C code
  109. ;; |1995/08/28 16:10:40|4.241|
  110.  
  111. ;;; Code:
  112.  
  113.  
  114. ;; user definable variables
  115. ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  116.  
  117. (defvar c-inhibit-startup-warnings-p nil
  118.   "*If non-nil, inhibits start up compatibility warnings.")
  119. (defvar c-strict-syntax-p nil
  120.   "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
  121. If the syntactic symbol for a particular line does not match a symbol
  122. in the offsets alist, an error is generated, otherwise no error is
  123. reported and the syntactic symbol is ignored.")
  124. (defvar c-echo-syntactic-information-p nil
  125.   "*If non-nil, syntactic info is echoed when the line is indented.")
  126. (defvar c-basic-offset 4
  127.   "*Amount of basic offset used by + and - symbols in `c-offsets-alist'.")
  128.  
  129. (defvar c-offsets-alist
  130.   '((string                . -1000)
  131.     (c                     . c-lineup-C-comments)
  132.     (defun-open            . 0)
  133.     (defun-close           . 0)
  134.     (defun-block-intro     . +)
  135.     (class-open            . 0)
  136.     (class-close           . 0)
  137.     (inline-open           . +)
  138.     (inline-close          . 0)
  139.     (ansi-funcdecl-cont    . -)
  140.     (knr-argdecl-intro     . +)
  141.     (knr-argdecl           . 0)
  142.     (topmost-intro         . 0)
  143.     (topmost-intro-cont    . 0)
  144.     (member-init-intro     . +)
  145.     (member-init-cont      . 0)
  146.     (inher-intro           . +)
  147.     (inher-cont            . c-lineup-multi-inher)
  148.     (block-open            . 0)
  149.     (block-close           . 0)
  150.     (brace-list-open       . 0)
  151.     (brace-list-close      . 0)
  152.     (brace-list-intro      . +)
  153.     (brace-list-entry      . 0)
  154.     (statement             . 0)
  155.     ;; some people might prefer
  156.     ;;(statement             . c-lineup-runin-statements)
  157.     (statement-cont        . +)
  158.     ;; some people might prefer
  159.     ;;(statement-cont        . c-lineup-math)
  160.     (statement-block-intro . +)
  161.     (statement-case-intro  . +)
  162.     (statement-case-open   . 0)
  163.     (substatement          . +)
  164.     (substatement-open     . +)
  165.     (case-label            . 0)
  166.     (access-label          . -)
  167.     (label                 . 2)
  168.     (do-while-closure      . 0)
  169.     (else-clause           . 0)
  170.     (comment-intro         . c-lineup-comment)
  171.     (arglist-intro         . +)
  172.     (arglist-cont          . 0)
  173.     (arglist-cont-nonempty . c-lineup-arglist)
  174.     (arglist-close         . +)
  175.     (stream-op             . c-lineup-streamop)
  176.     (inclass               . +)
  177.     (cpp-macro             . -1000)
  178.     (friend                . 0)
  179.     (objc-method-intro     . -1000)
  180.     (objc-method-args-cont . c-lineup-ObjC-method-args)
  181.     (objc-method-call-cont . c-lineup-ObjC-method-call)
  182.     )
  183.   "*Association list of syntactic element symbols and indentation offsets.
  184. As described below, each cons cell in this list has the form:
  185.  
  186.     (SYNTACTIC-SYMBOL . OFFSET)
  187.  
  188. When a line is indented, cc-mode first determines the syntactic
  189. context of the line by generating a list of symbols called syntactic
  190. elements.  This list can contain more than one syntactic element and
  191. the global variable `c-syntactic-context' contains the context list
  192. for the line being indented.  Each element in this list is actually a
  193. cons cell of the syntactic symbol and a buffer position.  This buffer
  194. position is call the relative indent point for the line.  Some
  195. syntactic symbols may not have a relative indent point associated with
  196. them.
  197.  
  198. After the syntactic context list for a line is generated, cc-mode
  199. calculates the absolute indentation for the line by looking at each
  200. syntactic element in the list.  First, it compares the syntactic
  201. element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it
  202. finds a match, it adds the OFFSET to the column of the relative indent
  203. point.  The sum of this calculation for each element in the syntactic
  204. list is the absolute offset for line being indented.
  205.  
  206. If the syntactic element does not match any in the `c-offsets-alist',
  207. an error is generated if `c-strict-syntax-p' is non-nil, otherwise
  208. the element is ignored.
  209.  
  210. Actually, OFFSET can be an integer, a function, a variable, or one of
  211. the following symbols: `+', `-', `++', `--', `*', or `/'.  These
  212. latter designate positive or negative multiples of `c-basic-offset',
  213. respectively: *1, *-1, *2, *-2, *0.5, and *-0.5. If OFFSET is a
  214. function, it is called with a single argument containing the cons of
  215. the syntactic element symbol and the relative indent point.  The
  216. function should return an integer offset.
  217.  
  218. Here is the current list of valid syntactic element symbols:
  219.  
  220.  string                 -- inside multi-line string
  221.  c                      -- inside a multi-line C style block comment
  222.  defun-open             -- brace that opens a function definition
  223.  defun-close            -- brace that closes a function definition
  224.  defun-block-intro      -- the first line in a top-level defun
  225.  class-open             -- brace that opens a class definition
  226.  class-close            -- brace that closes a class definition
  227.  inline-open            -- brace that opens an in-class inline method
  228.  inline-close           -- brace that closes an in-class inline method
  229.  ansi-funcdecl-cont     -- the nether region between an ANSI function
  230.                            declaration and the defun opening brace
  231.  knr-argdecl-intro      -- first line of a K&R C argument declaration
  232.  knr-argdecl            -- subsequent lines in a K&R C argument declaration
  233.  topmost-intro          -- the first line in a topmost construct definition
  234.  topmost-intro-cont     -- topmost definition continuation lines
  235.  member-init-intro      -- first line in a member initialization list
  236.  member-init-cont       -- subsequent member initialization list lines
  237.  inher-intro            -- first line of a multiple inheritance list
  238.  inher-cont             -- subsequent multiple inheritance lines
  239.  block-open             -- statement block open brace
  240.  block-close            -- statement block close brace
  241.  brace-list-open        -- open brace of an enum or static array list
  242.  brace-list-close       -- close brace of an enum or static array list
  243.  brace-list-intro       -- first line in an enum or static array list
  244.  brace-list-entry       -- subsequent lines in an enum or static array list
  245.  statement              -- a C/C++/ObjC statement
  246.  statement-cont         -- a continuation of a C/C++/ObjC statement
  247.  statement-block-intro  -- the first line in a new statement block
  248.  statement-case-intro   -- the first line in a case `block'
  249.  statement-case-open    -- the first line in a case block starting with brace
  250.  substatement           -- the first line after an if/while/for/do/else
  251.  substatement-open      -- the brace that opens a substatement block
  252.  case-label             -- a case or default label
  253.  access-label           -- C++ private/protected/public access label
  254.  label                  -- any non-special C/C++/ObjC label
  255.  do-while-closure       -- the `while' that ends a do/while construct
  256.  else-clause            -- the `else' of an if/else construct
  257.  comment-intro          -- a line containing only a comment introduction
  258.  arglist-intro          -- the first line in an argument list
  259.  arglist-cont           -- subsequent argument list lines when no
  260.                            arguments follow on the same line as the
  261.                            the arglist opening paren
  262.  arglist-cont-nonempty  -- subsequent argument list lines when at
  263.                            least one argument follows on the same
  264.                            line as the arglist opening paren
  265.  arglist-close          -- the solo close paren of an argument list
  266.  stream-op              -- lines continuing a stream operator construct
  267.  inclass                -- the construct is nested inside a class definition
  268.  cpp-macro              -- the start of a cpp macro
  269.  friend                 -- a C++ friend declaration
  270.  objc-method-intro      -- the first line of an Objective-C method definition
  271.  objc-method-args-cont  -- lines continuing an Objective-C method definition
  272.  objc-method-call-cont  -- lines continuing an Objective-C method call
  273. ")
  274.  
  275. (defvar c-tab-always-indent t
  276.   "*Controls the operation of the TAB key.
  277. If t, hitting TAB always just indents the current line.  If nil,
  278. hitting TAB indents the current line if point is at the left margin or
  279. in the line's indentation, otherwise it insert a real tab character.
  280. If other than nil or t, then tab is inserted only within literals
  281. -- defined as comments and strings -- and inside preprocessor
  282. directives, but line is always reindented.
  283.  
  284. Note that indentation of lines containing only comments is also
  285. controlled by the `c-comment-only-line-offset' variable.")
  286.  
  287. (defvar c-comment-only-line-offset 0
  288.   "*Extra offset for line which contains only the start of a comment.
  289. Can contain an integer or a cons cell of the form:
  290.  
  291.  (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
  292.  
  293. Where NON-ANCHORED-OFFSET is the amount of offset given to
  294. non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
  295. the amount of offset to give column-zero anchored comment-only lines.
  296. Just an integer as value is equivalent to (<val> . -1000).")
  297.  
  298. (defvar c-indent-comments-syntactically-p nil
  299.   "*Specifies how comment-only lines should be indented.
  300. When this variable is non-nil, comment-only lines are indented
  301. according to syntactic analysis via `c-offsets-alist', even when
  302. \\[indent-for-comment] is used.")
  303.  
  304. (defvar c-block-comments-indent-p nil
  305.   "*Specifies how to re-indent C style block comments.
  306.  
  307. Examples of the supported styles of C block comment indentation are
  308. shown below.  When this variable is nil, block comments are indented
  309. as shown in styles 1 through 4.  If this variable is non-nil, block
  310. comments are indented as shown in style 5.
  311.  
  312. Note that cc-mode does not automatically insert any stars or block
  313. comment delimiters.  You must type these in manually.  This variable
  314. only controls how the lines within the block comment are indented when
  315. you hit ``\\[c-indent-command]''.
  316.  
  317.  style 1:    style 2 (GNU):    style 3:     style 4:     style 5:
  318.  /*          /* Blah           /*           /*           /*
  319.     blah        blah.  */       * blah      ** blah      blah
  320.     blah                        * blah      ** blah      blah
  321.     */                          */          */           */")
  322.  
  323. (defvar c-cleanup-list '(scope-operator)
  324.   "*List of various C/C++/ObjC constructs to \"clean up\".
  325. These clean ups only take place when the auto-newline feature is turned
  326. on, as evidenced by the `/a' or `/ah' appearing next to the mode name.
  327. Valid symbols are:
  328.  
  329.  brace-else-brace    -- cleans up `} else {' constructs by placing entire
  330.                         construct on a single line.  This clean up only
  331.                         takes place when there is nothing but white
  332.                         space between the braces and the `else'.  Clean
  333.             up occurs when the open-brace after the `else'
  334.             is typed.
  335.  empty-defun-braces  -- cleans up empty defun braces by placing the
  336.                         braces on the same line.  Clean up occurs when
  337.             the defun closing brace is typed.
  338.  defun-close-semi    -- cleans up the terminating semi-colon on defuns
  339.             by placing the semi-colon on the same line as
  340.             the closing brace.  Clean up occurs when the
  341.             semi-colon is typed.
  342.  list-close-comma    -- cleans up commas following braces in array
  343.                         and aggregate initializers.  Clean up occurs
  344.             when the comma is typed.
  345.  scope-operator      -- cleans up double colons which may designate
  346.             a C++ scope operator split across multiple
  347.             lines. Note that certain C++ constructs can
  348.             generate ambiguous situations.  This clean up
  349.             only takes place when there is nothing but
  350.             whitespace between colons. Clean up occurs
  351.             when the second colon is typed.")
  352.  
  353. (defvar c-hanging-braces-alist '((brace-list-open)
  354.                  (substatement-open after)
  355.                  (block-close . c-snug-do-while))
  356.   "*Controls the insertion of newlines before and after braces.
  357. This variable contains an association list with elements of the
  358. following form: (SYNTACTIC-SYMBOL . ACTION).
  359.  
  360. When a brace (either opening or closing) is inserted, the syntactic
  361. context it defines is looked up in this list, and if found, the
  362. associated ACTION is used to determine where newlines are inserted.
  363. If the context is not found, the default is to insert a newline both
  364. before and after the brace.
  365.  
  366. SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
  367. class-close, inline-open, inline-close, block-open, block-close,
  368. substatement-open, statement-case-open, brace-list-open,
  369. brace-list-close, brace-list-intro, or brace-list-entry. See
  370. `c-offsets-alist' for details.
  371.  
  372. ACTION can be either a function symbol or a list containing any
  373. combination of the symbols `before' or `after'.  If the list is empty,
  374. no newlines are inserted either before or after the brace.
  375.  
  376. When ACTION is a function symbol, the function is called with a two
  377. arguments: the syntactic symbol for the brace and the buffer position
  378. at which the brace was inserted.  The function must return a list as
  379. described in the preceding paragraph.  Note that during the call to
  380. the function, the variable `c-syntactic-context' is set to the entire
  381. syntactic context for the brace line.")
  382.  
  383. (defvar c-hanging-colons-alist nil
  384.   "*Controls the insertion of newlines before and after certain colons.
  385. This variable contains an association list with elements of the
  386. following form: (SYNTACTIC-SYMBOL . ACTION).
  387.  
  388. See the variable `c-hanging-braces-alist' for the semantics of this
  389. variable.  Note however that making ACTION a function symbol is
  390. currently not supported for this variable.")
  391.  
  392. (defvar c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
  393.   "*List of functions that decide whether to insert a newline or not.
  394. The functions in this list are called, in order, whenever the
  395. auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
  396. string in the mode line), and a semicolon or comma is typed (see
  397. `c-electric-semi&comma').  Each function in this list is called with
  398. no arguments, and should return one of the following values:
  399.  
  400.   nil             -- no determination made, continue checking
  401.   'stop           -- do not insert a newline, and stop checking
  402.   (anything else) -- insert a newline, and stop checking
  403.  
  404. If every function in the list is called with no determination made,
  405. then no newline is inserted.")
  406.  
  407. (defvar c-hanging-comment-ender-p t
  408.   "*If nil, `c-fill-paragraph' leaves C block comment enders on their own line.
  409. Default value is t, which inhibits leaving block comment ending string
  410. `*/' on a line by itself.  This is BOCM's sole behavior.")
  411.  
  412. (defvar c-backslash-column 48
  413.   "*Column to insert backslashes when macroizing a region.")
  414. (defvar c-special-indent-hook nil
  415.   "*Hook for user defined special indentation adjustments.
  416. This hook gets called after a line is indented by the mode.")
  417. (defvar c-delete-function 'backward-delete-char-untabify
  418.   "*Function called by `c-electric-delete' when deleting characters.")
  419. (defvar c-electric-pound-behavior nil
  420.   "*List of behaviors for electric pound insertion.
  421. Only currently supported behavior is `alignleft'.")
  422.  
  423. (defvar c-recognize-knr-p nil
  424.   "*If non-nil, `c-mode' and `objc-mode' will recognize K&R constructs.
  425. This variable is needed because of ambiguities in C syntax that make
  426. fast recognition of K&R constructs problematic, and slow.  If you are
  427. coding with ANSI prototypes, set this variable to nil to speed up
  428. recognition of certain constructs.  By setting this variable to nil, I
  429. have seen an increase of 20 times under some circumstance.")
  430.  
  431. (defvar c-progress-interval 5
  432.   "*Interval used to update progress status during long re-indentation.
  433. If a number, percentage complete gets updated after each interval of
  434. that many seconds.   Set to nil to inhibit updating.  This is only
  435. useful for Emacs 19.")
  436.  
  437. (defvar c-style-alist
  438.   '(("GNU"
  439.      (c-basic-offset . 2)
  440.      (c-comment-only-line-offset . (0 . 0))
  441.      (c-offsets-alist . ((statement-block-intro . +)
  442.              (knr-argdecl-intro . 5)
  443.              (substatement-open . +)
  444.              (label . 0)
  445.              (statement-case-open . +)
  446.              (statement-cont . +)
  447.              (arglist-intro . c-lineup-arglist-intro-after-paren)
  448.              (arglist-close . c-lineup-arglist)
  449.              ))
  450.      )
  451.     ("K&R"
  452.      (c-basic-offset . 5)
  453.      (c-comment-only-line-offset . 0)
  454.      (c-offsets-alist . ((statement-block-intro . +)
  455.              (knr-argdecl-intro . 0)
  456.              (substatement-open . 0)
  457.              (label . 0)
  458.              (statement-cont . +)
  459.              ))
  460.      )
  461.     ("BSD"
  462.      (c-basic-offset . 4)
  463.      (c-comment-only-line-offset . 0)
  464.      (c-offsets-alist . ((statement-block-intro . +)
  465.              (knr-argdecl-intro . +)
  466.              (substatement-open . 0)
  467.              (label . 0)
  468.              (statement-cont . +)
  469.              ))
  470.      )
  471.     ("Stroustrup"
  472.      (c-basic-offset . 4)
  473.      (c-comment-only-line-offset . 0)
  474.      (c-offsets-alist . ((statement-block-intro . +)
  475.              (substatement-open . 0)
  476.              (label . 0)
  477.              (statement-cont . +)
  478.              ))
  479.      )
  480.     ("Whitesmith"
  481.      (c-basic-offset . 4)
  482.      (c-comment-only-line-offset . 0)
  483.      (c-offsets-alist . ((statement-block-intro . +)
  484.              (knr-argdecl-intro . +)
  485.              (substatement-open . 0)
  486.              (label . 0)
  487.              (statement-cont . +)
  488.              ))
  489.  
  490.      )
  491.     ("Ellemtel"
  492.      (c-basic-offset . 3)
  493.      (c-comment-only-line-offset . 0)
  494.      (c-hanging-braces-alist     . ((substatement-open before after)))
  495.      (c-offsets-alist . ((topmost-intro        . 0)
  496.                          (topmost-intro-cont   . 0)
  497.                          (substatement         . 3)
  498.              (substatement-open    . 0)
  499.              (statement-case-intro . 0)
  500.                          (case-label           . +)
  501.                          (access-label         . -3)
  502.                          (inclass              . 6)
  503.                          (inline-open          . 0)
  504.                          ))
  505.      ))
  506.   "Styles of Indentation.
  507. Elements of this alist are of the form:
  508.  
  509.   (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  510.  
  511. where STYLE-STRING is a short descriptive string used to select a
  512. style, VARIABLE is any cc-mode variable, and VALUE is the intended
  513. value for that variable when using the selected style.
  514.  
  515. There is one special case when VARIABLE is `c-offsets-alist'.  In this
  516. case, the VALUE is a list containing elements of the form:
  517.  
  518.   (SYNTACTIC-SYMBOL . VALUE)
  519.  
  520. as described in `c-offsets-alist'.  These are passed directly to
  521. `c-set-offset' so there is no need to set every syntactic symbol in
  522. your style, only those that are different from the default.
  523.  
  524. Note that all styles inherit from the \"CC-MODE\" style, which is
  525. computed at the time the mode is loaded.")
  526.  
  527. (defvar c-file-style nil
  528.   "*Variable interface for setting style via File Local Variables.
  529. In a file's Local Variable section, you can set this variable to a
  530. string suitable for `c-set-style'.  When the file is visited, cc-mode
  531. will set the style of the file to this value automatically.
  532.  
  533. Note that file style settings are applied before file offset settings
  534. as designated in the variable `c-file-offsets'.")
  535.  
  536. (defvar c-file-offsets nil
  537.   "*Variable interface for setting offsets via File Local Variables.
  538. In a file's Local Variable section, you can set this variable to an
  539. association list similiar to the values allowed in `c-offsets-alist'.
  540. When the file is visited, cc-mode will institute these offset settings
  541. automatically.
  542.  
  543. Note that file offset settings are applied after file style settings
  544. as designated in the variable `c-file-style'.")
  545.  
  546. (defvar c-mode-hook nil
  547.   "*Hook called by `c-mode'.")
  548. (defvar c++-mode-hook nil
  549.   "*Hook called by `c++-mode'.")
  550. (defvar objc-mode-hook nil
  551.   "*Hook called by `objc-mode'.")
  552.  
  553. (defvar c-mode-common-hook nil
  554.   "*Hook called by `c-mode', `c++-mode', and 'objc-mode' during common init.")
  555.  
  556. (defvar c-mode-menu
  557.   '(["Comment Out Region"     comment-region (mark)]
  558.     ["Macro Expand Region"    c-macro-expand (mark)]
  559.     ["Backslashify"           c-backslash-region (mark)]
  560.     ["Indent Expression"      c-indent-exp
  561.      (memq (following-char) '(?\( ?\[ ?\{))]
  562.     ["Indent Line"            c-indent-command t]
  563.     ["Fill Comment Paragraph" c-fill-paragraph t]
  564.     ["Up Conditional"         c-up-conditional t]
  565.     ["Backward Conditional"   c-backward-conditional t]
  566.     ["Forward Conditional"    c-forward-conditional t]
  567.     ["Backward Statement"     c-beginning-of-statement t]
  568.     ["Forward Statement"      c-end-of-statement t]
  569.     )
  570.   "XEmacs 19 (formerly Lucid) menu for C/C++/ObjC modes.")
  571.  
  572.  
  573. ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  574. ;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
  575.  
  576. ;; Shut the byte-compiler up. Requires Emacs 19 or JWZ's improved
  577. ;; byte-compiler. Otherwise, comment this line out and ignore
  578. ;; any warnings.
  579. ;;(byte-compiler-options (warnings nil))
  580.  
  581. ;; figure out what features this Emacs has
  582. (defconst c-emacs-features
  583.   (let ((major (and (boundp 'emacs-major-version)
  584.             emacs-major-version))
  585.     (minor (and (boundp 'emacs-minor-version)
  586.             emacs-minor-version))
  587.     flavor comments)
  588.     ;; figure out version numbers if not already discovered
  589.     (and (or (not major) (not minor))
  590.      (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
  591.      (setq major (string-to-int (substring emacs-version
  592.                            (match-beginning 1)
  593.                            (match-end 1)))
  594.            minor (string-to-int (substring emacs-version
  595.                            (match-beginning 2)
  596.                            (match-end 2)))))
  597.     (if (not (and major minor))
  598.     (error "Cannot figure out the major and minor version numbers."))
  599.     ;; calculate the major version
  600.     (cond
  601.      ((= major 18) (setq major 'v18))    ;Emacs 18
  602.      ((= major 4)  (setq major 'v18))    ;Epoch 4
  603.      ((= major 19) (setq major 'v19    ;Emacs 19
  604.              flavor (if (or (string-match "Lucid" emacs-version)
  605.                     (string-match "XEmacs" emacs-version))
  606.                     'XEmacs 'FSF)))
  607.      ;; I don't know
  608.      (t (error "Cannot recognize major version number: %s" major)))
  609.     ;; All XEmacs 19's (formerly Lucid) use 8-bit modify-syntax-entry
  610.     ;; flags, as do all patched (obsolete) FSF Emacs 19, Emacs 18,
  611.     ;; Epoch 4's.  Only vanilla FSF Emacs 19 uses 1-bit flag.  Lets be
  612.     ;; as smart as we can about figuring this out.
  613.     (if (eq major 'v19)
  614.     (let ((table (copy-syntax-table)))
  615.       (modify-syntax-entry ?a ". 12345678" table)
  616.       (if (= (logand (lsh (aref table ?a) -16) 255) 255)
  617.           (setq comments '8-bit)
  618.         (setq comments '1-bit)))
  619.       (setq comments 'no-dual-comments))
  620.     ;; lets do some minimal sanity checking.
  621.     (if (and (or
  622.           ;; Lemacs before 19.6 had bugs
  623.           (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
  624.           ;; FSF 19 before 19.21 has known bugs
  625.           (and (eq major 'v19) (eq flavor 'FSF) (< minor 21)))
  626.          (not c-inhibit-startup-warnings-p))
  627.     (with-output-to-temp-buffer "*cc-mode warnings*"
  628.       (print (format
  629. "The version of Emacs that you are running, %s,
  630. has known bugs in its syntax.c parsing routines which will affect the
  631. performance of cc-mode. You should strongly consider upgrading to the
  632. latest available version.  cc-mode may continue to work, after a
  633. fashion, but strange indentation errors could be encountered."
  634.              emacs-version))))
  635.     ;; Emacs 18, with no patch is not too good
  636.     (if (and (eq major 'v18) (eq comments 'no-dual-comments)
  637.          (not c-inhibit-startup-warnings-p))
  638.     (with-output-to-temp-buffer "*cc-mode warnings*"
  639.       (print (format
  640. "The version of Emacs 18 you are running, %s,
  641. has known deficiencies in its ability to handle dual C++ comments,
  642. i.e. C++ line style comments and C block style comments.  This will
  643. not be much of a problem for you if you are only editing C code, but
  644. if you are doing much C++ editing, you should strongly consider
  645. upgrading to one of the latest Emacs 19's.  In Emacs 18, you may also
  646. experience performance degradations. Emacs 19 has some new built-in
  647. routines which will speed things up for you.
  648.  
  649. Because of these inherent problems, cc-mode is no longer being
  650. actively maintained for Emacs 18, however, until you can upgrade to
  651. Emacs 19, you may want to look at cc-mode-18.el in the cc-mode
  652. distribution.  THIS FILE IS COMPLETELY UNSUPPORTED!  If you use it,
  653. you are on your own, although patch contributions will be folded into
  654. the main release."
  655.                 emacs-version))))
  656.     ;; Emacs 18 with the syntax patches are no longer supported
  657.     (if (and (eq major 'v18) (not (eq comments 'no-dual-comments))
  658.          (not c-inhibit-startup-warnings-p))
  659.     (with-output-to-temp-buffer "*cc-mode warnings*"
  660.       (print (format
  661. "You are running a syntax patched Emacs 18 variant.  While this should
  662. work for you, you may want to consider upgrading to one of the latest
  663. Emacs 19's (FSF or XEmacs -- formerly Lucid).  The syntax patches are
  664. no longer supported either for syntax.c or cc-mode."))))
  665.     (list major comments))
  666.   "A list of features extant in the Emacs you are using.
  667. There are many flavors of Emacs out there, each with different
  668. features supporting those needed by cc-mode.  Here's the current
  669. supported list, along with the values for this variable:
  670.  
  671.  Vanilla Emacs 18/Epoch 4:   (v18 no-dual-comments)
  672.  Emacs 18/Epoch 4 (patch2):  (v18 8-bit)
  673.  XEmacs (formerly Lucid) 19: (v19 8-bit)
  674.  FSF Emacs 19:               (v19 1-bit).")
  675.  
  676. (defvar c++-mode-abbrev-table nil
  677.   "Abbrev table in use in c++-mode buffers.")
  678. (define-abbrev-table 'c++-mode-abbrev-table ())
  679.  
  680. (defvar c-mode-abbrev-table nil
  681.   "Abbrev table in use in c-mode buffers.")
  682. (define-abbrev-table 'c-mode-abbrev-table ())
  683.  
  684. (defvar objc-mode-abbrev-table nil
  685.   "Abbrev table in use in objc-mode buffers.")
  686. (define-abbrev-table 'objc-mode-abbrev-table ())
  687.  
  688. (defun c-mode-fsf-menu (name map)
  689.   ;; Add FSF menu to a keymap.  FSF menus suck.  Don't add them for
  690.   ;; XEmacs. This feature test will fail on other than FSF's Emacs 19.
  691.   (condition-case nil
  692.       (progn
  693.     (define-key map [menu-bar] (make-sparse-keymap))
  694.     (define-key map [menu-bar c] (cons name (make-sparse-keymap name)))
  695.  
  696.     (define-key map [menu-bar c comment-region]
  697.       '("Comment Out Region" . comment-region))
  698.     (define-key map [menu-bar c c-macro-expand]
  699.       '("Macro Expand Region" . c-macro-expand))
  700.     (define-key map [menu-bar c c-backslash-region]
  701.       '("Backslashify" . c-backslash-region))
  702.     (define-key map [menu-bar c indent-exp]
  703.       '("Indent Expression" . c-indent-exp))
  704.     (define-key map [menu-bar c indent-line]
  705.       '("Indent Line" . c-indent-command))
  706.     (define-key map [menu-bar c fill]
  707.       '("Fill Comment Paragraph" . c-fill-paragraph))
  708.     (define-key map [menu-bar c up]
  709.       '("Up Conditional" . c-up-conditional))
  710.     (define-key map [menu-bar c backward]
  711.       '("Backward Conditional" . c-backward-conditional))
  712.     (define-key map [menu-bar c forward]
  713.       '("Forward Conditional" . c-forward-conditional))
  714.     (define-key map [menu-bar c backward-stmt]
  715.       '("Backward Statement" . c-beginning-of-statement))
  716.     (define-key map [menu-bar c forward-stmt]
  717.       '("Forward Statement" . c-end-of-statement))
  718.  
  719.     ;; RMS: mouse-3 should not select this menu.  mouse-3's global
  720.     ;; definition is useful in C mode and we should not interfere
  721.     ;; with that.  The menu is mainly for beginners, and for them,
  722.     ;; the menubar requires less memory than a special click.
  723.     t)
  724.     (error nil)))
  725.  
  726. (defvar c-mode-map ()
  727.   "Keymap used in c-mode buffers.")
  728. (if c-mode-map
  729.     ()
  730.   ;; TBD: should we even worry about naming this keymap. My vote: no,
  731.   ;; because FSF and XEmacs (formerly Lucid) do it differently.
  732.   (setq c-mode-map (make-sparse-keymap))
  733.   ;; put standard keybindings into MAP
  734.   ;; the following mappings correspond more or less directly to BOCM
  735.   (define-key c-mode-map "{"         'c-electric-brace)
  736.   (define-key c-mode-map "}"         'c-electric-brace)
  737.   (define-key c-mode-map ";"         'c-electric-semi&comma)
  738.   (define-key c-mode-map "#"         'c-electric-pound)
  739.   (define-key c-mode-map ":"         'c-electric-colon)
  740.   ;; Lemacs 19.9 defines these two, the second of which is commented out
  741.   ;; (define-key c-mode-map "\e{" 'c-insert-braces)
  742.   ;; Commented out electric square brackets because nobody likes them.
  743.   ;; (define-key c-mode-map "[" 'c-insert-brackets)
  744.   (define-key c-mode-map "\e\C-h"    'c-mark-function)
  745.   (define-key c-mode-map "\e\C-q"    'c-indent-exp)
  746.   (define-key c-mode-map "\ea"       'c-beginning-of-statement)
  747.   (define-key c-mode-map "\ee"       'c-end-of-statement)
  748.   ;; I'd rather use an adaptive fill program instead of this.
  749.   (define-key c-mode-map "\eq"       'c-fill-paragraph)
  750.   (define-key c-mode-map "\C-c\C-n"  'c-forward-conditional)
  751.   (define-key c-mode-map "\C-c\C-p"  'c-backward-conditional)
  752.   (define-key c-mode-map "\C-c\C-u"  'c-up-conditional)
  753.   (define-key c-mode-map "\t"        'c-indent-command)
  754.   (define-key c-mode-map "\177"      'c-electric-delete)
  755.   ;; these are new keybindings, with no counterpart to BOCM
  756.   (define-key c-mode-map ","         'c-electric-semi&comma)
  757.   (define-key c-mode-map "/"         'c-electric-slash)
  758.   (define-key c-mode-map "*"         'c-electric-star)
  759.   (define-key c-mode-map "\C-c\C-q"  'c-indent-defun)
  760.   (define-key c-mode-map "\C-c\C-\\" 'c-backslash-region)
  761.   ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
  762.   (define-key c-mode-map "\C-c\C-a"  'c-toggle-auto-state)
  763.   (define-key c-mode-map "\C-c\C-b"  'c-submit-bug-report)
  764.   (define-key c-mode-map "\C-c\C-c"  'comment-region)
  765.   (define-key c-mode-map "\C-c\C-d"  'c-toggle-hungry-state)
  766.   (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
  767.   (define-key c-mode-map "\C-c\C-o"  'c-set-offset)
  768.   (define-key c-mode-map "\C-c\C-s"  'c-show-syntactic-information)
  769.   (define-key c-mode-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
  770.   ;; conflicts with OOBR
  771.   ;;(define-key c-mode-map "\C-c\C-v"  'c-version)
  772.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  773.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  774.   (if (and (not (c-mode-fsf-menu "C" c-mode-map))
  775.        ;; in XEmacs (formerly Lucid) 19, we want the menu to popup
  776.        ;; when the 3rd button is hit.  In 19.10 and beyond this is
  777.        ;; done automatically if we put the menu on mode-popup-menu
  778.        ;; variable, see c-common-init. RMS decided that this
  779.        ;; feature should not be included for FSF's Emacs.
  780.        (boundp 'current-menubar)
  781.        (not (boundp 'mode-popup-menu)))
  782.       (define-key c-mode-map 'button3 'c-popup-menu)))
  783.  
  784. (defvar c++-mode-map ()
  785.   "Keymap used in c++-mode buffers.")
  786. (if c++-mode-map
  787.     ()
  788.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  789.   (if (memq 'v19 c-emacs-features)
  790.       ;; XEmacs (formerly Lucid) and FSF Emacs 19 do this differently
  791.       (if (not (fboundp 'set-keymap-parent))
  792.       (setq c++-mode-map (cons 'keymap c-mode-map))
  793.     (setq c++-mode-map (make-sparse-keymap))
  794.     (set-keymap-parent c++-mode-map c-mode-map))
  795.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  796.     (setq c++-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  797.   ;; add bindings which are only useful for C++
  798.   (define-key c++-mode-map "\C-c:"  'c-scope-operator)
  799.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  800.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  801.   (c-mode-fsf-menu "C++" c++-mode-map))
  802.  
  803. (defvar objc-mode-map ()
  804.   "Keymap used in objc-mode buffers.")
  805. (if objc-mode-map
  806.     ()
  807.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  808.   (if (memq 'v19 c-emacs-features)
  809.       ;; XEmacs (formerly Lucid) and FSF Emacs 19 do this differently
  810.       (if (not (fboundp 'set-keymap-parent))
  811.       (setq objc-mode-map (cons 'keymap c-mode-map))
  812.     (setq objc-mode-map (make-sparse-keymap))
  813.     (set-keymap-parent objc-mode-map c-mode-map))
  814.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  815.     (setq objc-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  816.   ;; add bindings which are only useful for Objective-C
  817.   ;;
  818.   ;; no additional bindings
  819.   ;;
  820.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  821.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  822.   (c-mode-fsf-menu "ObjC" objc-mode-map))
  823.  
  824. (defun c-populate-syntax-table (table)
  825.   ;; Populate the syntax TABLE
  826.   ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
  827.   (modify-syntax-entry ?_  "_"     table)
  828.   (modify-syntax-entry ?\\ "\\"    table)
  829.   (modify-syntax-entry ?+  "."     table)
  830.   (modify-syntax-entry ?-  "."     table)
  831.   (modify-syntax-entry ?=  "."     table)
  832.   (modify-syntax-entry ?%  "."     table)
  833.   (modify-syntax-entry ?<  "."     table)
  834.   (modify-syntax-entry ?>  "."     table)
  835.   (modify-syntax-entry ?&  "."     table)
  836.   (modify-syntax-entry ?|  "."     table)
  837.   (modify-syntax-entry ?\' "\""    table))
  838.  
  839. (defun c-setup-dual-comments (table)
  840.   ;; Set up TABLE to handle block and line style comments
  841.   (cond
  842.    ((memq '8-bit c-emacs-features)
  843.     ;; XEmacs (formerly Lucid) has the best implementation
  844.     (modify-syntax-entry ?/  ". 1456" table)
  845.     (modify-syntax-entry ?*  ". 23"   table)
  846.     (modify-syntax-entry ?\n "> b"    table)
  847.     ;; Give CR the same syntax as newline, for selective-display
  848.     (modify-syntax-entry ?\^m "> b"    table))
  849.    ((memq '1-bit c-emacs-features)
  850.     ;; FSF Emacs 19 does things differently, but we can work with it
  851.     (modify-syntax-entry ?/  ". 124b" table)
  852.     (modify-syntax-entry ?*  ". 23"   table)
  853.     (modify-syntax-entry ?\n "> b"    table)
  854.     ;; Give CR the same syntax as newline, for selective-display
  855.     (modify-syntax-entry ?\^m "> b"   table))
  856.    ))
  857.  
  858. (defvar c-mode-syntax-table nil
  859.   "Syntax table used in c-mode buffers.")
  860. (if c-mode-syntax-table
  861.     ()
  862.   (setq c-mode-syntax-table (make-syntax-table))
  863.   (c-populate-syntax-table c-mode-syntax-table)
  864.   ;; add extra comment syntax
  865.   (modify-syntax-entry ?/  ". 14"  c-mode-syntax-table)
  866.   (modify-syntax-entry ?*  ". 23"  c-mode-syntax-table))
  867.  
  868. (defvar c++-mode-syntax-table nil
  869.   "Syntax table used in c++-mode buffers.")
  870. (if c++-mode-syntax-table
  871.     ()
  872.   (setq c++-mode-syntax-table (make-syntax-table))
  873.   (c-populate-syntax-table c++-mode-syntax-table)
  874.   ;; add extra comment syntax
  875.   (c-setup-dual-comments c++-mode-syntax-table)
  876.   ;; TBD: does it make sense for colon to be symbol class in C++?
  877.   ;; I'm not so sure, since c-label-key is busted on lines like:
  878.   ;; Foo::bar( i );
  879.   ;; maybe c-label-key should be fixed instead of commenting this out,
  880.   ;; but it also bothers me that this only seems appropriate for C++
  881.   ;; and not C.
  882.   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
  883.   )
  884.  
  885. (defvar objc-mode-syntax-table nil
  886.   "Syntax table used in objc-mode buffers.")
  887. (if objc-mode-syntax-table
  888.     ()
  889.   (setq objc-mode-syntax-table (make-syntax-table))
  890.   (c-populate-syntax-table objc-mode-syntax-table)
  891.   ;; add extra comment syntax
  892.   (c-setup-dual-comments objc-mode-syntax-table)
  893.   ;; everyone gets these
  894.   (modify-syntax-entry ?@ "_" objc-mode-syntax-table)
  895.   )
  896.  
  897. (defvar c-hungry-delete-key nil
  898.   "Internal state of hungry delete key feature.")
  899. (defvar c-auto-newline nil
  900.   "Internal state of auto newline feature.")
  901. (defvar c-auto-hungry-string nil
  902.   "Internal auto-newline/hungry-delete designation string for mode line.")
  903. (defvar c-syntactic-context nil
  904.   "Variable containing syntactic analysis list during indentation.")
  905. (defvar c-comment-start-regexp nil
  906.   "Buffer local variable describing how comment are introduced.")
  907. (defvar c-conditional-key nil
  908.   "Buffer local language-specific conditional keyword regexp.")
  909. (defvar c-access-key nil
  910.   "Buffer local language-specific access key regexp.")
  911. (defvar c-class-key nil
  912.   "Buffer local language-specific class key regexp.")
  913. (defconst c-protection-key
  914.   "\\<\\(public\\|protected\\|private\\)\\>"
  915.   "Regexp describing protection keywords.")
  916. (defconst c-symbol-key "\\(\\w\\|\\s_\\)+"
  917.   "Regexp describing a C/C++/ObjC symbol.
  918. We cannot use just `word' syntax class since `_' cannot be in word
  919. class.  Putting underscore in word class breaks forward word movement
  920. behavior that users are familiar with.")
  921. (defconst c-baseclass-key
  922.   (concat
  923.    ":?[ \t]*\\(virtual[ \t]+\\)?\\("
  924.    c-protection-key "[ \t]+\\)" c-symbol-key)
  925.   "Regexp describing C++ base classes in a derived class definition.")
  926.  
  927. ;; minor mode variables
  928. (make-variable-buffer-local 'c-auto-newline)
  929. (make-variable-buffer-local 'c-hungry-delete-key)
  930. (make-variable-buffer-local 'c-auto-hungry-string)
  931. ;; language differences
  932. (make-variable-buffer-local 'c-comment-start-regexp)
  933. (make-variable-buffer-local 'c-conditional-key)
  934. (make-variable-buffer-local 'c-access-key)
  935. (make-variable-buffer-local 'c-class-key)
  936. (make-variable-buffer-local 'c-baseclass-key)
  937. (make-variable-buffer-local 'c-recognize-knr-p)
  938. ;; style variables are made buffer local at tail end of this file.
  939.  
  940. ;; cmacexp is lame because it uses no preprocessor symbols.
  941. ;; It isn't very extensible either -- hardcodes /lib/cpp.
  942. ;; [I add it here only because c-mode has it -- BAW]]
  943. ;;(autoload 'c-macro-expand "cmacexp"
  944. ;;  "Display the result of expanding all C macros occurring in the region.
  945. ;;The expansion is entirely correct because it uses the C preprocessor."
  946. ;;  t)
  947.  
  948.  
  949. ;; constant regular expressions for looking at various constructs
  950. (defconst c-C++-class-key "\\(class\\|struct\\|union\\)"
  951.   "Regexp describing a C++ class declaration, including templates.")
  952. (defconst c-C-class-key "\\(struct\\|union\\)"
  953.   "Regexp describing a C struct declaration.")
  954. (defconst c-inher-key
  955.   (concat "\\(\\<static\\>\\s +\\)?"
  956.       c-C++-class-key "[ \t]+" c-symbol-key
  957.       "\\([ \t]*:[ \t]*\\)?\\s *[^;]")
  958.   "Regexp describing a class inheritance declaration.")
  959. (defconst c-switch-label-key
  960.   "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):"
  961.   "Regexp describing a switch's case or default label")
  962. (defconst c-C++-access-key
  963.   (concat c-protection-key ":")
  964.   "Regexp describing C++ access specification keywords.")
  965. (defconst c-label-key
  966.   (concat c-symbol-key ":\\([^:]\\|$\\)")
  967.   "Regexp describing any label.")
  968. (defconst c-C-conditional-key
  969.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\)\\b[^_]"
  970.   "Regexp describing a conditional control.")
  971. (defconst c-C++-conditional-key
  972.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\|try\\|catch\\)\\b[^_]"
  973.   "Regexp describing a conditional control for C++.")
  974. (defconst c-C++-friend-key
  975.   "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+"
  976.   "Regexp describing friend declarations in C++ classes.")
  977. (defconst c-C++-comment-start-regexp "//\\|/\\*"
  978.   "Dual comment value for `c-comment-start-regexp'.")
  979. (defconst c-C-comment-start-regexp "/\\*"
  980.   "Single comment style value for `c-comment-start-regexp'.")
  981.  
  982. (defconst c-ObjC-method-key
  983.   (concat
  984.    "^\\s *[+-]\\s *"
  985.    "\\(([^)]*)\\)?"            ; return type
  986.    ;; \\s- in objc syntax table does not include \n
  987.    ;; since it is considered the end of //-comments.
  988.    "[ \t\n]*" c-symbol-key)
  989.   "Regexp describing an Objective-C method intro.")
  990. (defconst c-ObjC-access-key
  991.   (concat "@" c-protection-key)
  992.   "Regexp describing access specification keywords for Objective-C.")
  993. (defconst c-ObjC-class-key
  994.   (concat
  995.    "@\\(interface\\|implementation\\)\\s +"
  996.    c-symbol-key                ;name of the class
  997.    "\\(\\s *:\\s *" c-symbol-key "\\)?"    ;maybe followed by the superclass
  998.    "\\(\\s *<[^>]+>\\)?"        ;and maybe the adopted protocols list
  999.    )
  1000.   "Regexp describing a class or protocol declaration for Objective-C.")
  1001.  
  1002. ;; KLUDGE ALERT.  We default these variables to their `C' values so
  1003. ;; that non-cc-mode-ized modes that depend on c-mode will still work
  1004. ;; out of the box.  The most glaring example is awk-mode.  There ought
  1005. ;; to be a better way.
  1006. (setq-default c-conditional-key c-C-conditional-key
  1007.           c-class-key c-C-class-key
  1008.           c-comment-start-regexp c-C-comment-start-regexp)
  1009.  
  1010.  
  1011. ;; main entry points for the modes
  1012. (defconst c-list-of-mode-names nil)
  1013.  
  1014. (defun c++-mode ()
  1015.   "Major mode for editing C++ code.
  1016. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  1017. c++-mode buffer.  This automatically sets up a mail buffer with
  1018. version information already added.  You just need to add a description
  1019. of the problem, including a reproducable test case and send the
  1020. message.
  1021.  
  1022. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1023.  
  1024. Note that the details of configuring c++-mode have been moved to the
  1025. accompanying texinfo manual (which is not yet completed -- volunteers
  1026. are welcome).  Until then, please read the README file that came with
  1027. the cc-mode distribution.
  1028.  
  1029. The hook variable `c++-mode-hook' is run with no args, if that
  1030. variable is bound and has a non-nil value.  Also the common hook
  1031. c-mode-common-hook is run first, by this defun, `c-mode', and `objc-mode'.
  1032.  
  1033. Key bindings:
  1034. \\{c++-mode-map}"
  1035.   (interactive)
  1036.   (kill-all-local-variables)
  1037.   (set-syntax-table c++-mode-syntax-table)
  1038.   (setq major-mode 'c++-mode
  1039.     mode-name "C++"
  1040.     local-abbrev-table c++-mode-abbrev-table)
  1041.   (use-local-map c++-mode-map)
  1042.   (c-common-init)
  1043.   (setq comment-start "// "
  1044.     comment-end ""
  1045.     comment-multi-line nil
  1046.     c-conditional-key c-C++-conditional-key
  1047.     c-comment-start-regexp c-C++-comment-start-regexp
  1048.     c-class-key c-C++-class-key
  1049.     c-access-key c-C++-access-key)
  1050.   (run-hooks 'c-mode-common-hook)
  1051.   (run-hooks 'c++-mode-hook))
  1052. (setq c-list-of-mode-names (cons "C++" c-list-of-mode-names))
  1053.  
  1054. (defun c-mode ()
  1055.   "Major mode for editing K&R and ANSI C code.
  1056. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  1057. c-mode buffer.  This automatically sets up a mail buffer with version
  1058. information already added.  You just need to add a description of the
  1059. problem, including a reproducable test case and send the message.
  1060.  
  1061. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1062.  
  1063. Note that the details of configuring c-mode have been moved to the
  1064. accompanying texinfo manual (which is not yet completed -- volunteers
  1065. are welcome).  Until then, please read the README file that came with
  1066. the cc-mode distribution.
  1067.  
  1068. The hook variable `c-mode-hook' is run with no args, if that value is
  1069. bound and has a non-nil value.  Also the common hook
  1070. c-mode-common-hook is run first, by this defun, `c++-mode', and `objc-mode'.
  1071.  
  1072. Key bindings:
  1073. \\{c-mode-map}"
  1074.   (interactive)
  1075.   (kill-all-local-variables)
  1076.   (set-syntax-table c-mode-syntax-table)
  1077.   (setq major-mode 'c-mode
  1078.     mode-name "C"
  1079.     local-abbrev-table c-mode-abbrev-table)
  1080.   (use-local-map c-mode-map)
  1081.   (c-common-init)
  1082.   (setq comment-start "/* "
  1083.     comment-end   " */"
  1084.     comment-multi-line t
  1085.     c-conditional-key c-C-conditional-key
  1086.     c-class-key c-C-class-key
  1087.     c-baseclass-key nil
  1088.     c-comment-start-regexp c-C-comment-start-regexp)
  1089.   (run-hooks 'c-mode-common-hook)
  1090.   (run-hooks 'c-mode-hook))
  1091. (setq c-list-of-mode-names (cons "C" c-list-of-mode-names))
  1092.  
  1093. (defun objc-mode ()
  1094.   "Major mode for editing Objective C code.
  1095. To submit a problem report, enter `\\[c-submit-bug-report]' from an
  1096. objc-mode buffer.  This automatically sets up a mail buffer with
  1097. version information already added.  You just need to add a description
  1098. of the problem, including a reproducable test case and send the
  1099. message.
  1100.  
  1101. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1102.  
  1103. Note that the details of configuring objc-mode have been moved to the
  1104. accompanying texinfo manual (which is not yet completed -- volunteers
  1105. are welcome).  Until then, please read the README file that came with
  1106. the cc-mode distribution.
  1107.  
  1108. The hook variable `objc-mode-hook' is run with no args, if that value
  1109. is bound and has a non-nil value.  Also the common hook
  1110. c-mode-common-hook is run first, by this defun, `c-mode', and `c++-mode'.
  1111.  
  1112. Key bindings:
  1113. \\{objc-mode-map}"
  1114.   (interactive)
  1115.   (kill-all-local-variables)
  1116.   (set-syntax-table objc-mode-syntax-table)
  1117.   (setq major-mode 'objc-mode
  1118.     mode-name "ObjC"
  1119.     local-abbrev-table objc-mode-abbrev-table)
  1120.   (use-local-map objc-mode-map)
  1121.   (c-common-init)
  1122.   (setq comment-start "// "
  1123.     comment-end   ""
  1124.     comment-multi-line nil
  1125.     c-conditional-key c-C-conditional-key
  1126.     c-comment-start-regexp c-C++-comment-start-regexp
  1127.      c-class-key c-ObjC-class-key
  1128.     c-baseclass-key nil
  1129.     c-access-key c-ObjC-access-key)
  1130.   (run-hooks 'c-mode-common-hook)
  1131.   (run-hooks 'objc-mode-hook))
  1132. (setq c-list-of-mode-names (cons "ObjC" c-list-of-mode-names))
  1133.  
  1134. (defun c-common-init ()
  1135.   ;; Common initializations for c++-mode and c-mode.
  1136.   ;; make local variables
  1137.   (make-local-variable 'paragraph-start)
  1138.   (make-local-variable 'paragraph-separate)
  1139.   (make-local-variable 'paragraph-ignore-fill-prefix)
  1140.   (make-local-variable 'require-final-newline)
  1141.   (make-local-variable 'parse-sexp-ignore-comments)
  1142.   (make-local-variable 'indent-line-function)
  1143.   (make-local-variable 'indent-region-function)
  1144.   (make-local-variable 'comment-start)
  1145.   (make-local-variable 'comment-end)
  1146.   (make-local-variable 'comment-column)
  1147.   (make-local-variable 'comment-start-skip)
  1148.   (make-local-variable 'outline-regexp)
  1149.   (make-local-variable 'outline-level)
  1150.   ;; now set their values
  1151.   (setq paragraph-start (concat "^$\\|" page-delimiter)
  1152.     paragraph-separate paragraph-start
  1153.     paragraph-ignore-fill-prefix t
  1154.     require-final-newline t
  1155.     parse-sexp-ignore-comments t
  1156.     indent-line-function 'c-indent-line
  1157.     indent-region-function 'c-indent-region
  1158.     outline-regexp "[^#\n\^M]"
  1159.     outline-level 'c-outline-level
  1160.     comment-column 32
  1161.     comment-start-skip "/\\*+ *\\|// *")
  1162.   ;; we have to do something special for c-offsets-alist so that the
  1163.   ;; buffer local value has its own alist structure.
  1164.   (setq c-offsets-alist (copy-alist c-offsets-alist))
  1165.   ;; setup the comment indent variable in a Emacs version portable way
  1166.   ;; ignore any byte compiler warnings you might get here
  1167.   (if (boundp 'comment-indent-function)
  1168.       (progn
  1169.        (make-local-variable 'comment-indent-function)
  1170.        (setq comment-indent-function 'c-comment-indent))
  1171.     (make-local-variable 'comment-indent-hook)
  1172.     (setq comment-indent-hook 'c-comment-indent))
  1173.   ;; put C menu into menubar and on popup menu for XEmacs (formerly
  1174.   ;; Lucid) 19. I think this happens automatically for FSF Emacs 19.
  1175.   (if (and (boundp 'current-menubar)
  1176.        current-menubar
  1177.        (not (assoc mode-name current-menubar)))
  1178.       ;; its possible that this buffer has changed modes from one of
  1179.       ;; the other cc-mode modes.  In that case, only the menubar
  1180.       ;; title of the menu changes.
  1181.       (let ((modes (copy-sequence c-list-of-mode-names))
  1182.         changed-p)
  1183.     (setq modes (delete major-mode modes))
  1184.     (while modes
  1185.       (if (not (assoc (car modes) current-menubar))
  1186.           (setq modes (cdr modes))
  1187.         (relabel-menu-item (list (car modes)) mode-name)
  1188.         (setq modes nil
  1189.           changed-p t)))
  1190.     (if (not changed-p)
  1191.         (progn
  1192.           (set-buffer-menubar (copy-sequence current-menubar))
  1193.           (add-menu nil mode-name c-mode-menu)))))
  1194.   (if (boundp 'mode-popup-menu)
  1195.       (setq mode-popup-menu
  1196.         (cons (concat mode-name " Mode Commands") c-mode-menu)))
  1197.   ;; put auto-hungry designators onto minor-mode-alist, but only once
  1198.   (or (assq 'c-auto-hungry-string minor-mode-alist)
  1199.       (setq minor-mode-alist
  1200.         (cons '(c-auto-hungry-string c-auto-hungry-string)
  1201.           minor-mode-alist))))
  1202.  
  1203. (defun c-postprocess-file-styles ()
  1204.   "Function that post processes relevent file local variables.
  1205. Currently, this function simply applies any style and offset settings
  1206. found in the file's Local Variable list.  It first applies any style
  1207. setting found in `c-file-style', then it applies any offset settings
  1208. it finds in `c-file-offsets'."
  1209.   ;; apply file styles and offsets
  1210.   (and c-file-style
  1211.        (c-set-style c-file-style))
  1212.   (and c-file-offsets
  1213.        (mapcar
  1214.     (function
  1215.      (lambda (langentry)
  1216.        (let ((langelem (car langentry))
  1217.          (offset (cdr langentry)))
  1218.          (c-set-offset langelem offset)
  1219.          )))
  1220.     c-file-offsets)))
  1221.  
  1222. ;; Add the posprocessing function to hack-local-variables-hook.  As of
  1223. ;; 28-Aug-1995, XEmacs 19.12 and Emacs 19.29 support this.
  1224. (and (fboundp 'add-hook)
  1225.      (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
  1226.  
  1227. (defun c-enable-//-in-c-mode ()
  1228.   "Enables // as a comment delimiter in `c-mode'.
  1229. ANSI C currently does *not* allow this, although many C compilers
  1230. support optional C++ style comments.  To use, call this function from
  1231. your `.emacs' file before you visit any C files.  The changes are
  1232. global and affect all future `c-mode' buffers."
  1233.   (c-setup-dual-comments c-mode-syntax-table)
  1234.   (setq-default c-C-comment-start-regexp c-C++-comment-start-regexp))
  1235.  
  1236.  
  1237. ;; macros must be defined before first use
  1238. (defmacro c-point (position)
  1239.   ;; Returns the value of point at certain commonly referenced POSITIONs.
  1240.   ;; POSITION can be one of the following symbols:
  1241.   ;; 
  1242.   ;; bol  -- beginning of line
  1243.   ;; eol  -- end of line
  1244.   ;; bod  -- beginning of defun
  1245.   ;; boi  -- back to indentation
  1246.   ;; ionl -- indentation of next line
  1247.   ;; iopl -- indentation of previous line
  1248.   ;; bonl -- beginning of next line
  1249.   ;; bopl -- beginning of previous line
  1250.   ;; 
  1251.   ;; This function does not modify point or mark.
  1252.   (or (and (eq 'quote (car-safe position))
  1253.        (null (cdr (cdr position))))
  1254.       (error "bad buffer position requested: %s" position))
  1255.   (setq position (nth 1 position))
  1256.   (` (let ((here (point)))
  1257.        (,@ (cond
  1258.         ((eq position 'bol)  '((beginning-of-line)))
  1259.         ((eq position 'eol)  '((end-of-line)))
  1260.         ((eq position 'bod)
  1261.          '((beginning-of-defun)
  1262.            ;; if defun-prompt-regexp is non-nil, b-o-d won't leave
  1263.            ;; us at the open brace.
  1264.            (and (boundp 'defun-prompt-regexp)
  1265.             defun-prompt-regexp
  1266.             (looking-at defun-prompt-regexp)
  1267.             (goto-char (match-end 0)))
  1268.            ))
  1269.         ((eq position 'boi)  '((back-to-indentation)))
  1270.         ((eq position 'bonl) '((forward-line 1)))
  1271.         ((eq position 'bopl) '((forward-line -1)))
  1272.         ((eq position 'iopl)
  1273.          '((forward-line -1)
  1274.            (back-to-indentation)))
  1275.         ((eq position 'ionl)
  1276.          '((forward-line 1)
  1277.            (back-to-indentation)))
  1278.         (t (error "unknown buffer position requested: %s" position))
  1279.         ))
  1280.        (prog1
  1281.        (point)
  1282.      (goto-char here))
  1283.        ;; workaround for an Emacs18 bug -- blech! Well, at least it
  1284.        ;; doesn't hurt for v19
  1285.        (,@ nil)
  1286.        )))
  1287.  
  1288. (defmacro c-auto-newline ()
  1289.   ;; if auto-newline feature is turned on, insert a newline character
  1290.   ;; and return t, otherwise return nil.
  1291.   (` (and c-auto-newline
  1292.       (not (c-in-literal))
  1293.       (not (newline)))))
  1294.  
  1295. (defmacro c-safe (&rest body)
  1296.   ;; safely execute BODY, return nil if an error occurred
  1297.   (` (condition-case nil
  1298.      (progn (,@ body))
  1299.        (error nil))))
  1300.  
  1301. (defun c-insert-special-chars (arg)
  1302.   ;; simply call self-insert-command in Emacs 19
  1303.   (self-insert-command (prefix-numeric-value arg)))
  1304.  
  1305. (defun c-intersect-lists (list alist)
  1306.   ;; return the element of ALIST that matches the first element found
  1307.   ;; in LIST.  Uses assq.
  1308.   (let (match)
  1309.     (while (and list
  1310.         (not (setq match (assq (car list) alist))))
  1311.       (setq list (cdr list)))
  1312.     match))
  1313.  
  1314. (defun c-lookup-lists (list alist1 alist2)
  1315.   ;; first, find the first entry from LIST that is present in ALIST1,
  1316.   ;; then find the entry in ALIST2 for that entry.
  1317.   (assq (car (c-intersect-lists list alist1)) alist2))
  1318.  
  1319.  
  1320. ;; This is used by indent-for-comment to decide how much to indent a
  1321. ;; comment in C code based on its context.
  1322. (defun c-comment-indent ()
  1323.   (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
  1324.       0                ;Existing comment at bol stays there.
  1325.     (let ((opoint (point))
  1326.       placeholder)
  1327.       (save-excursion
  1328.     (beginning-of-line)
  1329.     (cond
  1330.      ;; CASE 1: A comment following a solitary close-brace should
  1331.      ;; have only one space.
  1332.      ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
  1333.                   c-comment-start-regexp
  1334.                   "\\)"))
  1335.       (search-forward "}")
  1336.       (1+ (current-column)))
  1337.      ;; CASE 2: 2 spaces after #endif
  1338.      ((or (looking-at "^#[ \t]*endif[ \t]*")
  1339.           (looking-at "^#[ \t]*else[ \t]*"))
  1340.       7)
  1341.      ;; CASE 3: when comment-column is nil, calculate the offset
  1342.      ;; according to c-offsets-alist.  E.g. identical to hitting
  1343.      ;; TAB.
  1344.      ((and c-indent-comments-syntactically-p
  1345.            (save-excursion
  1346.          (skip-chars-forward " \t")
  1347.          (or (looking-at comment-start)
  1348.              (eolp))))
  1349.       (let ((syntax (c-guess-basic-syntax)))
  1350.         ;; BOGOSITY ALERT: if we're looking at the eol, its
  1351.         ;; because indent-for-comment hasn't put the comment-start
  1352.         ;; in the buffer yet.  this will screw up the syntactic
  1353.         ;; analysis so we kludge in the necessary info.  Another
  1354.         ;; kludge is that if we're at the bol, then we really want
  1355.         ;; to ignore any anchoring as specified by
  1356.         ;; c-comment-only-line-offset since it doesn't apply here.
  1357.         (if (save-excursion
  1358.           (beginning-of-line)
  1359.           (skip-chars-forward " \t")
  1360.           (eolp))
  1361.         (c-add-syntax 'comment-intro))
  1362.         (let ((c-comment-only-line-offset
  1363.            (if (consp c-comment-only-line-offset)
  1364.                c-comment-only-line-offset
  1365.              (cons c-comment-only-line-offset
  1366.                c-comment-only-line-offset))))
  1367.           (apply '+ (mapcar 'c-get-offset syntax)))))
  1368.      ;; CASE 4: use comment-column if previous line is a
  1369.      ;; comment-only line indented to the left of comment-column
  1370.      ((save-excursion
  1371.         (beginning-of-line)
  1372.         (and (not (bobp))
  1373.          (forward-line -1))
  1374.         (skip-chars-forward " \t")
  1375.         (prog1
  1376.         (looking-at c-comment-start-regexp)
  1377.           (setq placeholder (point))))
  1378.       (goto-char placeholder)
  1379.       (if (< (current-column) comment-column)
  1380.           comment-column
  1381.         (current-column)))
  1382.      ;; CASE 5: If comment-column is 0, and nothing but space
  1383.      ;; before the comment, align it at 0 rather than 1.
  1384.      ((progn
  1385.         (goto-char opoint)
  1386.         (skip-chars-backward " \t")
  1387.         (and (= comment-column 0) (bolp)))
  1388.       0)
  1389.      ;; CASE 6: indent at comment column except leave at least one
  1390.      ;; space.
  1391.      (t (max (1+ (current-column))
  1392.          comment-column))
  1393.      )))))
  1394.  
  1395. ;; used by outline-minor-mode
  1396. (defun c-outline-level ()
  1397.   (save-excursion
  1398.     (skip-chars-forward "\t ")
  1399.     (current-column)))
  1400.  
  1401. ;; active regions, and auto-newline/hungry delete key
  1402. (defun c-keep-region-active ()
  1403.   ;; do whatever is necessary to keep the region active in XEmacs
  1404.   ;; (formerly Lucid). ignore byte-compiler warnings you might see
  1405.   (and (boundp 'zmacs-region-stays)
  1406.        (setq zmacs-region-stays t)))
  1407.  
  1408. (defun c-update-modeline ()
  1409.   ;; set the c-auto-hungry-string for the correct designation on the modeline
  1410.   (setq c-auto-hungry-string
  1411.     (if c-auto-newline
  1412.         (if c-hungry-delete-key "/ah" "/a")
  1413.       (if c-hungry-delete-key "/h" nil)))
  1414.   ;; updates the modeline for all Emacsen
  1415.   (if (memq 'v19 c-emacs-features)
  1416.       (force-mode-line-update)
  1417.     (set-buffer-modified-p (buffer-modified-p))))
  1418.  
  1419. (defun c-calculate-state (arg prevstate)
  1420.   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
  1421.   ;; arg is nil or zero, toggle the state. If arg is negative, turn
  1422.   ;; the state off, and if arg is positive, turn the state on
  1423.   (if (or (not arg)
  1424.       (zerop (setq arg (prefix-numeric-value arg))))
  1425.       (not prevstate)
  1426.     (> arg 0)))
  1427.  
  1428. (defun c-toggle-auto-state (arg)
  1429.   "Toggle auto-newline feature.
  1430. Optional numeric ARG, if supplied turns on auto-newline when positive,
  1431. turns it off when negative, and just toggles it when zero.
  1432.  
  1433. When the auto-newline feature is enabled (as evidenced by the `/a' or
  1434. `/ah' on the modeline after the mode name) newlines are automatically
  1435. inserted after special characters such as brace, comma, semi-colon,
  1436. and colon."
  1437.   (interactive "P")
  1438.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1439.   (c-update-modeline)
  1440.   (c-keep-region-active))
  1441.  
  1442. (defun c-toggle-hungry-state (arg)
  1443.   "Toggle hungry-delete-key feature.
  1444. Optional numeric ARG, if supplied turns on hungry-delete when positive,
  1445. turns it off when negative, and just toggles it when zero.
  1446.  
  1447. When the hungry-delete-key feature is enabled (as evidenced by the
  1448. `/h' or `/ah' on the modeline after the mode name) the delete key
  1449. gobbles all preceding whitespace in one fell swoop."
  1450.   (interactive "P")
  1451.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1452.   (c-update-modeline)
  1453.   (c-keep-region-active))
  1454.  
  1455. (defun c-toggle-auto-hungry-state (arg)
  1456.   "Toggle auto-newline and hungry-delete-key features.
  1457. Optional numeric ARG, if supplied turns on auto-newline and
  1458. hungry-delete when positive, turns them off when negative, and just
  1459. toggles them when zero.
  1460.  
  1461. See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
  1462.   (interactive "P")
  1463.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1464.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1465.   (c-update-modeline)
  1466.   (c-keep-region-active))
  1467.  
  1468.  
  1469. ;; COMMANDS
  1470. (defun c-electric-delete (arg)
  1471.   "Deletes preceding character or whitespace.
  1472. If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  1473. \"/ah\" string on the mode line, then all preceding whitespace is
  1474. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  1475. nil, or point is inside a literal then the function in the variable
  1476. `c-delete-function' is called."
  1477.   (interactive "P")
  1478.   (if (or (not c-hungry-delete-key)
  1479.       arg
  1480.       (c-in-literal))
  1481.       (funcall c-delete-function (prefix-numeric-value arg))
  1482.     (let ((here (point)))
  1483.       (skip-chars-backward " \t\n")
  1484.       (if (/= (point) here)
  1485.       (delete-region (point) here)
  1486.     (funcall c-delete-function 1)
  1487.     ))))
  1488.  
  1489. (defun c-electric-pound (arg)
  1490.   "Electric pound (`#') insertion.
  1491. Inserts a `#' character specially depending on the variable
  1492. `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if
  1493. point is inside a literal, nothing special happens."
  1494.   (interactive "P")
  1495.   (if (or (c-in-literal)
  1496.       arg
  1497.       (not (memq 'alignleft c-electric-pound-behavior)))
  1498.       ;; do nothing special
  1499.       (self-insert-command (prefix-numeric-value arg))
  1500.     ;; place the pound character at the left edge
  1501.     (let ((pos (- (point-max) (point)))
  1502.       (bolp (bolp)))
  1503.       (beginning-of-line)
  1504.       (delete-horizontal-space)
  1505.       (insert-char last-command-char 1)
  1506.       (and (not bolp)
  1507.        (goto-char (- (point-max) pos)))
  1508.       )))
  1509.  
  1510. (defun c-electric-brace (arg)
  1511.   "Insert a brace.
  1512.  
  1513. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1514. or \"/ah\" string on the mode line, newlines are inserted before and
  1515. after braces based on the value of `c-hanging-braces-alist'.
  1516.  
  1517. Also, the line is re-indented unless a numeric ARG is supplied, there
  1518. are non-whitespace characters present on the line after the brace, or
  1519. the brace is inserted inside a literal."
  1520.   (interactive "P")
  1521.   (let* ((c-state-cache (c-parse-state))
  1522.      (safepos (c-safe-position (point) c-state-cache))
  1523.      (literal (c-in-literal safepos)))
  1524.     ;; if we're in a literal, or we're not at the end of the line, or
  1525.     ;; a numeric arg is provided, or auto-newlining is turned off,
  1526.     ;; then just insert the character.
  1527.     (if (or literal arg
  1528. ;        (not c-auto-newline)
  1529.         (not (looking-at "[ \t]*$")))
  1530.     (c-insert-special-chars arg)    
  1531.       (let* ((syms '(class-open class-close defun-open defun-close 
  1532.              inline-open inline-close brace-list-open brace-list-close
  1533.              brace-list-intro brace-list-entry block-open block-close
  1534.              substatement-open statement-case-open))
  1535.         ;; we want to inhibit blinking the paren since this will
  1536.         ;; be most disruptive. we'll blink it ourselves later on
  1537.         (old-blink-paren (if (boundp 'blink-paren-function)
  1538.                  blink-paren-function
  1539.                    blink-paren-hook))
  1540.         blink-paren-function    ; emacs19
  1541.         blink-paren-hook        ; emacs18
  1542.         (insertion-point (point))
  1543.         delete-temp-newline
  1544.         (preserve-p (= 32 (char-syntax (preceding-char))))
  1545.         ;; shut this up too
  1546.         (c-echo-syntactic-information-p nil)
  1547.         (syntax (progn
  1548.               ;; only insert a newline if there is
  1549.               ;; non-whitespace behind us
  1550.               (if (save-excursion
  1551.                 (skip-chars-backward " \t")
  1552.                 (not (bolp)))
  1553.               (progn (newline)
  1554.                  (setq delete-temp-newline t)))
  1555.               (self-insert-command (prefix-numeric-value arg))
  1556.               ;; state cache doesn't change
  1557.               (c-guess-basic-syntax)))
  1558.         (newlines (and
  1559.                c-auto-newline
  1560.                (or (c-lookup-lists syms syntax c-hanging-braces-alist)
  1561.                '(ignore before after)))))
  1562.     ;; If syntax is a function symbol, then call it using the
  1563.     ;; defined semantics.
  1564.     (if (and (not (consp (cdr newlines)))
  1565.          (fboundp (cdr newlines)))
  1566.         (let ((c-syntactic-context syntax))
  1567.           (setq newlines
  1568.             (funcall (cdr newlines) (car newlines) insertion-point))))
  1569.     ;; does a newline go before the open brace?
  1570.     (if (memq 'before newlines)
  1571.         ;; we leave the newline we've put in there before,
  1572.         ;; but we need to re-indent the line above
  1573.         (let ((pos (- (point-max) (point)))
  1574.           (here (point))
  1575.           (c-state-cache c-state-cache))
  1576.           (forward-line -1)
  1577.           ;; we may need to update the cache. this should still be
  1578.           ;; faster than recalculating the state in many cases
  1579.           (save-excursion
  1580.         (save-restriction
  1581.           (narrow-to-region here (point))
  1582.           (if (and (c-safe (progn (backward-up-list -1) t))
  1583.                (memq (preceding-char) '(?\) ?}))
  1584.                (progn (widen)
  1585.                   (c-safe (progn (forward-sexp -1) t))))
  1586.               (setq c-state-cache
  1587.                 (c-hack-state (point) 'open c-state-cache))
  1588.             (if (and (car c-state-cache)
  1589.                  (not (consp (car c-state-cache)))
  1590.                  (<= (point) (car c-state-cache)))
  1591.             (setq c-state-cache (cdr c-state-cache))
  1592.               ))))
  1593.           (let ((here (point))
  1594.             (shift (c-indent-line)))
  1595.         (setq c-state-cache (c-adjust-state (c-point 'bol) here
  1596.                             (- shift) c-state-cache)))
  1597.           (goto-char (- (point-max) pos))
  1598.           ;; if the buffer has changed due to the indentation, we
  1599.           ;; need to recalculate syntax for the current line, but
  1600.           ;; we won't need to update the state cache.
  1601.           (if (/= (point) here)
  1602.           (setq syntax (c-guess-basic-syntax))))
  1603.       ;; must remove the newline we just stuck in (if we really did it)
  1604.       (and delete-temp-newline
  1605.            (save-excursion
  1606.          ;; if there is whitespace before point, then preserve
  1607.          ;; at least one space.
  1608.          (delete-indentation)
  1609.          (just-one-space)
  1610.          (if (not preserve-p)
  1611.              (delete-char -1))))
  1612.       ;; since we're hanging the brace, we need to recalculate
  1613.       ;; syntax.  Update the state to accurately reflect the
  1614.       ;; beginning of the line.  We punt if we cross any open or
  1615.       ;; closed parens because its just too hard to modify the
  1616.       ;; known state.  This limitation will be fixed in v5.
  1617.       (save-excursion
  1618.         (let ((bol (c-point 'bol)))
  1619.           (if (zerop (car (parse-partial-sexp bol (1- (point)))))
  1620.           (setq c-state-cache (c-whack-state bol c-state-cache)
  1621.             syntax (c-guess-basic-syntax))
  1622.         ;; gotta punt. this requires some horrible kludgery
  1623.         (beginning-of-line)
  1624.         (makunbound 'c-state-cache)
  1625.         (setq c-state-cache (c-parse-state)
  1626.               syntax nil))))
  1627.       )
  1628.     ;; now adjust the line's indentation. don't update the state
  1629.     ;; cache since c-guess-basic-syntax isn't called when the
  1630.     ;; syntax is passed to c-indent-line
  1631.     (let ((here (point))
  1632.           (shift (c-indent-line syntax)))
  1633.       (setq c-state-cache (c-adjust-state (c-point 'bol) here
  1634.                           (- shift) c-state-cache)))
  1635.     ;; Do all appropriate clean ups
  1636.     (let ((here (point))
  1637.           (pos (- (point-max) (point)))
  1638.           mbeg mend)
  1639.       ;; clean up empty defun braces
  1640.       (if (and c-auto-newline
  1641.            (memq 'empty-defun-braces c-cleanup-list)
  1642.            (= last-command-char ?\})
  1643.            (c-intersect-lists '(defun-close class-close inline-close)
  1644.                       syntax)
  1645.            (progn
  1646.              (forward-char -1)
  1647.              (skip-chars-backward " \t\n")
  1648.              (= (preceding-char) ?\{))
  1649.            ;; make sure matching open brace isn't in a comment
  1650.            (not (c-in-literal)))
  1651.           (delete-region (point) (1- here)))
  1652.       ;; clean up brace-else-brace
  1653.       (if (and c-auto-newline
  1654.            (memq 'brace-else-brace c-cleanup-list)
  1655.            (= last-command-char ?\{)
  1656.            (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
  1657.            (progn
  1658.              (setq mbeg (match-beginning 0)
  1659.                mend (match-end 0))
  1660.              (= mend here))
  1661.            (not (c-in-literal)))
  1662.           (progn
  1663.         (delete-region mbeg mend)
  1664.         (insert "} else {")))
  1665.       (goto-char (- (point-max) pos))
  1666.       )
  1667.     ;; does a newline go after the brace?
  1668.     (if (memq 'after newlines)
  1669.         (progn
  1670.           (newline)
  1671.           ;; update on c-state-cache
  1672.           (let* ((bufpos (- (point) 2))
  1673.              (which (if (= (char-after bufpos) ?{) 'open 'close))
  1674.              (c-state-cache (c-hack-state bufpos which c-state-cache)))
  1675.         (c-indent-line))))
  1676.     ;; blink the paren
  1677.     (and (= last-command-char ?\})
  1678.          old-blink-paren
  1679.          (save-excursion
  1680.            (c-backward-syntactic-ws safepos)
  1681.            (if (boundp 'blink-paren-function)
  1682.            (funcall old-blink-paren)
  1683.          (run-hooks old-blink-paren))))
  1684.     ))))
  1685.       
  1686. (defun c-electric-slash (arg)
  1687.   "Insert a slash character.
  1688. If slash is second of a double-slash C++ style comment introducing
  1689. construct, and we are on a comment-only-line, indent line as comment.
  1690. If numeric ARG is supplied or point is inside a literal, indentation
  1691. is inhibited."
  1692.   (interactive "P")
  1693.   (let ((indentp (and (memq major-mode '(c++-mode objc-mode))
  1694.               (not arg)
  1695.               (= (preceding-char) ?/)
  1696.               (= last-command-char ?/)
  1697.               (not (c-in-literal))))
  1698.     ;; shut this up
  1699.     (c-echo-syntactic-information-p nil))
  1700.     (self-insert-command (prefix-numeric-value arg))
  1701.     (if indentp
  1702.     (c-indent-line))))
  1703.  
  1704. (defun c-electric-star (arg)
  1705.   "Insert a star character.
  1706. If the star is the second character of a C style comment introducing
  1707. construct, and we are on a comment-only-line, indent line as comment.
  1708. If numeric ARG is supplied or point is inside a literal, indentation
  1709. is inhibited."
  1710.   (interactive "P")
  1711.   (self-insert-command (prefix-numeric-value arg))
  1712.   ;; if we are in a literal, or if arg is given do not re-indent the
  1713.   ;; current line, unless this star introduces a comment-only line.
  1714.   (if (and (not arg)
  1715.        (memq (c-in-literal) '(c))
  1716.        (= (preceding-char) ?*)
  1717.        (save-excursion
  1718.          (forward-char -1)
  1719.          (skip-chars-backward "*")
  1720.          (if (= (preceding-char) ?/)
  1721.          (forward-char -1))
  1722.          (skip-chars-backward " \t")
  1723.          (bolp)))
  1724.       ;; shut this up
  1725.       (let (c-echo-syntactic-information-p)
  1726.     (c-indent-line))
  1727.     ))
  1728.  
  1729. (defun c-electric-semi&comma (arg)
  1730.   "Insert a comma or semicolon.
  1731. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  1732. or \"/ah\" string on the mode line, a newline might be inserted.  See
  1733. the variable `c-hanging-semi&comma-criteria' for how newline insertion
  1734. is determined.
  1735.  
  1736. When semicolon is inserted, the line is re-indented unless a numeric
  1737. arg is supplied, point is inside a literal, or there are
  1738. non-whitespace characters on the line following the semicolon."
  1739.   (interactive "P")
  1740.   (let* ((lim (c-most-enclosing-brace (c-parse-state)))
  1741.      (literal (c-in-literal lim))
  1742.      (here (point))
  1743.      ;; shut this up
  1744.      (c-echo-syntactic-information-p nil))
  1745.     (if (or literal
  1746.         arg
  1747.         (not (looking-at "[ \t]*$")))
  1748.     (c-insert-special-chars arg)
  1749.       ;; do some special stuff with the character
  1750.       (self-insert-command (prefix-numeric-value arg))
  1751.       ;; do all cleanups, reindentations, and newline insertions, but
  1752.       ;; only if c-auto-newline is turned on
  1753.       (if (not c-auto-newline) nil
  1754.     ;; clean ups
  1755.     (let ((pos (- (point-max) (point))))
  1756.       (if (and (or (and
  1757.             (= last-command-char ?,)
  1758.             (memq 'list-close-comma c-cleanup-list))
  1759.                (and
  1760.             (= last-command-char ?\;)
  1761.             (memq 'defun-close-semi c-cleanup-list)))
  1762.            (progn
  1763.              (forward-char -1)
  1764.              (skip-chars-backward " \t\n")
  1765.              (= (preceding-char) ?}))
  1766.            ;; make sure matching open brace isn't in a comment
  1767.            (not (c-in-literal lim)))
  1768.           (delete-region (point) here))
  1769.       (goto-char (- (point-max) pos)))
  1770.     ;; re-indent line
  1771.     (c-indent-line)
  1772.     ;; check to see if a newline should be added
  1773.     (let ((criteria c-hanging-semi&comma-criteria)
  1774.           answer add-newline-p)
  1775.       (while criteria
  1776.         (setq answer (funcall (car criteria)))
  1777.         ;; only nil value means continue checking
  1778.         (if (not answer)
  1779.         (setq criteria (cdr criteria))
  1780.           (setq criteria nil)
  1781.           ;; only 'stop specifically says do not add a newline
  1782.           (setq add-newline-p (not (eq answer 'stop)))
  1783.           ))
  1784.       (if add-newline-p
  1785.           (progn (newline)
  1786.              (c-indent-line)))
  1787.       )))))
  1788.  
  1789. (defun c-semi&comma-inside-parenlist ()
  1790.   "Determine if a newline should be added after a semicolon.
  1791. If a comma was inserted, no determination is made.  If a semicolon was
  1792. inserted inside a parenthesis list, no newline is added otherwise a
  1793. newline is added.  In either case, checking is stopped.  This supports
  1794. exactly the old newline insertion behavior."
  1795.   ;; newline only after semicolon, but only if that semicolon is not
  1796.   ;; inside a parenthesis list (e.g. a for loop statement)
  1797.   (if (/= last-command-char ?\;)
  1798.       nil                ; continue checking
  1799.     (if (condition-case nil
  1800.         (save-excursion
  1801.           (up-list -1)
  1802.           (/= (following-char) ?\())
  1803.       (error t))
  1804.     t
  1805.       'stop)))
  1806.  
  1807. (defun c-electric-colon (arg)
  1808.   "Insert a colon.
  1809.  
  1810. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1811. or \"/ah\" string on the mode line, newlines are inserted before and
  1812. after colons based on the value of `c-hanging-colons-alist'.
  1813.  
  1814. Also, the line is re-indented unless a numeric ARG is supplied, there
  1815. are non-whitespace characters present on the line after the colon, or
  1816. the colon is inserted inside a literal.
  1817.  
  1818. This function cleans up double colon scope operators based on the
  1819. value of `c-cleanup-list'."
  1820.   (interactive "P")
  1821.   (let* ((bod (c-point 'bod))
  1822.      (literal (c-in-literal bod))
  1823.      syntax newlines
  1824.      ;; shut this up
  1825.      (c-echo-syntactic-information-p nil))
  1826.     (if (or literal
  1827.         arg
  1828.         (not (looking-at "[ \t]*$")))
  1829.     (c-insert-special-chars arg)
  1830.       ;; insert the colon, then do any specified cleanups
  1831.       (self-insert-command (prefix-numeric-value arg))
  1832.       (let ((pos (- (point-max) (point)))
  1833.         (here (point)))
  1834.     (if (and c-auto-newline
  1835.          (memq 'scope-operator c-cleanup-list)
  1836.          (= (preceding-char) ?:)
  1837.          (progn
  1838.            (forward-char -1)
  1839.            (skip-chars-backward " \t\n")
  1840.            (= (preceding-char) ?:))
  1841.          (not (c-in-literal))
  1842.          (not (= (char-after (- (point) 2)) ?:)))
  1843.         (delete-region (point) (1- here)))
  1844.     (goto-char (- (point-max) pos)))
  1845.       ;; lets do some special stuff with the colon character
  1846.       (setq syntax (c-guess-basic-syntax)
  1847.         ;; some language elements can only be determined by
  1848.         ;; checking the following line.  Lets first look for ones
  1849.         ;; that can be found when looking on the line with the
  1850.         ;; colon
  1851.         newlines
  1852.         (and c-auto-newline
  1853.          (or (c-lookup-lists '(case-label label access-label)
  1854.                      syntax c-hanging-colons-alist)
  1855.              (c-lookup-lists '(member-init-intro inher-intro)
  1856.                      (prog2
  1857.                      (insert "\n")
  1858.                      (c-guess-basic-syntax)
  1859.                        (delete-char -1))
  1860.                      c-hanging-colons-alist))))
  1861.       ;; indent the current line
  1862.       (c-indent-line syntax)
  1863.       ;; does a newline go before the colon?  Watch out for already
  1864.       ;; non-hung colons.  However, we don't unhang them because that
  1865.       ;; would be a cleanup (and anti-social).
  1866.       (if (and (memq 'before newlines)
  1867.            (save-excursion
  1868.          (skip-chars-backward ": \t")
  1869.          (not (bolp))))
  1870.       (let ((pos (- (point-max) (point))))
  1871.         (forward-char -1)
  1872.         (newline)
  1873.         (c-indent-line)
  1874.         (goto-char (- (point-max) pos))))
  1875.       ;; does a newline go after the colon?
  1876.       (if (memq 'after (cdr-safe newlines))
  1877.       (progn
  1878.         (newline)
  1879.         (c-indent-line)))
  1880.       )))
  1881.  
  1882. ;; set up electric character functions to work with pending-del,
  1883. ;; (a.k.a. delsel) mode.  All symbols get the t value except
  1884. ;; c-electric-delete which gets 'supercede.
  1885. (mapcar
  1886.  (function
  1887.   (lambda (sym)
  1888.     (put sym 'delete-selection t)    ; for delsel (FSF)
  1889.     (put sym 'pending-delete t)))    ; for pending-del (XEmacs)
  1890.  '(c-electric-pound
  1891.    c-electric-brace
  1892.    c-electric-slash
  1893.    c-electric-star
  1894.    c-electric-semi&comma
  1895.    c-electric-colon))
  1896. (put 'c-electric-delete 'delete-selection 'supersede) ; delsel
  1897. (put 'c-electric-delete 'pending-delete   'supersede) ; pending-del
  1898.  
  1899.  
  1900.  
  1901. (defun c-read-offset (langelem)
  1902.   ;; read new offset value for LANGELEM from minibuffer. return a
  1903.   ;; legal value only
  1904.   (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
  1905.      (defstr (format "(default %s): " oldoff))
  1906.      (errmsg (concat "Offset must be int, func, var, "
  1907.              "or in [+,-,++,--,*,/] "
  1908.              defstr))
  1909.      (prompt (concat "Offset " defstr))
  1910.      offset input interned)
  1911.     (while (not offset)
  1912.       (setq input (read-string prompt)
  1913.         offset (cond ((string-equal "" input) oldoff)  ; default
  1914.              ((string-equal "+" input) '+)
  1915.              ((string-equal "-" input) '-)
  1916.              ((string-equal "++" input) '++)
  1917.              ((string-equal "--" input) '--)
  1918.              ((string-equal "*" input) '*)
  1919.              ((string-equal "/" input) '/)
  1920.              ((string-match "^-?[0-9]+$" input)
  1921.               (string-to-int input))
  1922.              ((fboundp (setq interned (intern input)))
  1923.               interned)
  1924.              ((boundp interned) interned)
  1925.              ;; error, but don't signal one, keep trying
  1926.              ;; to read an input value
  1927.              (t (ding)
  1928.                 (setq prompt errmsg)
  1929.                 nil))))
  1930.     offset))
  1931.  
  1932. (defun c-set-offset (symbol offset &optional add-p)
  1933.   "Change the value of a syntactic element symbol in `c-offsets-alist'.
  1934. SYMBOL is the syntactic element symbol to change and OFFSET is the new
  1935. offset for that syntactic element.  Optional ADD says to add SYMBOL to
  1936. `c-offsets-alist' if it doesn't already appear there."
  1937.   (interactive
  1938.    (let* ((langelem
  1939.        (intern (completing-read
  1940.             (concat "Syntactic symbol to change"
  1941.                 (if current-prefix-arg " or add" "")
  1942.                 ": ")
  1943.             (mapcar
  1944.              (function
  1945.               (lambda (langelem)
  1946.             (cons (format "%s" (car langelem)) nil)))
  1947.              c-offsets-alist)
  1948.             nil (not current-prefix-arg)
  1949.             ;; initial contents tries to be the last element
  1950.             ;; on the syntactic analysis list for the current
  1951.             ;; line
  1952.             (let* ((syntax (c-guess-basic-syntax))
  1953.                (len (length syntax))
  1954.                (ic (format "%s" (car (nth (1- len) syntax)))))
  1955.               (if (memq 'v19 c-emacs-features)
  1956.               (cons ic 0)
  1957.             ic))
  1958.             )))
  1959.       (offset (c-read-offset langelem)))
  1960.      (list langelem offset current-prefix-arg)))
  1961.   ;; sanity check offset
  1962.   (or (eq offset '+)
  1963.       (eq offset '-)
  1964.       (eq offset '++)
  1965.       (eq offset '--)
  1966.       (eq offset '*)
  1967.       (eq offset '/)
  1968.       (integerp offset)
  1969.       (fboundp offset)
  1970.       (boundp offset)
  1971.       (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
  1972.          offset))
  1973.   (let ((entry (assq symbol c-offsets-alist)))
  1974.     (if entry
  1975.     (setcdr entry offset)
  1976.       (if add-p
  1977.       (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
  1978.     (error "%s is not a valid syntactic symbol." symbol))))
  1979.   (c-keep-region-active))
  1980.  
  1981. (defun c-set-style-1 (stylevars)
  1982.   ;; given a style's variable alist, institute the style
  1983.   (mapcar
  1984.    (function
  1985.     (lambda (conscell)
  1986.       (let ((attr (car conscell))
  1987.         (val  (cdr conscell)))
  1988.     ;; KLUDGE ALERT: special case for c-offsets-alist
  1989.     (if (not (eq attr 'c-offsets-alist))
  1990.         (set attr val)
  1991.       (mapcar
  1992.        (function
  1993.         (lambda (langentry)
  1994.           (let ((langelem (car langentry))
  1995.             (offset (cdr langentry)))
  1996.         (c-set-offset langelem offset)
  1997.         )))
  1998.        val))
  1999.     )))
  2000.    stylevars))
  2001.  
  2002. (defun c-set-style (stylename)
  2003.   "Set cc-mode variables to use one of several different indentation styles.
  2004. STYLENAME is a string representing the desired style from the list of
  2005. styles described in the variable `c-style-alist'.  See that variable
  2006. for details of setting up styles."
  2007.   (interactive (list (let ((completion-ignore-case t)
  2008.                (prompt (format "Which %s indentation style? "
  2009.                        mode-name)))
  2010.                (completing-read prompt c-style-alist nil t))))
  2011.   (let ((vars (cdr (assoc stylename c-style-alist)))
  2012.     (default (cdr (assoc "CC-MODE" c-style-alist))))
  2013.     (or vars (error "Invalid indentation style `%s'" stylename))
  2014.     (or default (error "No \"CC-MODE\" style found!"))
  2015.     ;; first reset the style to CC-MODE to give every style a common
  2016.     ;; base. Then institute the new style.
  2017.     (c-set-style-1 default)
  2018.     (if (not (string= stylename "CC-MODE"))
  2019.     (c-set-style-1 vars)))
  2020.   (c-keep-region-active))
  2021.  
  2022. (defun c-add-style (style descrip &optional set-p)
  2023.   "Adds a style to `c-style-alist', or updates an existing one.
  2024. STYLE is a string identifying the style to add or update.  DESCRIP is
  2025. an association list describing the style and must be of the form:
  2026.  
  2027.   ((VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  2028.  
  2029. See the variable `c-style-alist' for the semantics of VARIABLE and
  2030. VALUE.  This function also sets the current style to STYLE using
  2031. `c-set-style' if the optional SET-P flag is non-nil."
  2032.   (interactive
  2033.    (let ((stylename (completing-read "Style to add: " c-style-alist))
  2034.      (description (eval-minibuffer "Style description: ")))
  2035.      (list stylename description
  2036.        (y-or-n-p "Set the style too? "))))
  2037.   (let ((s (assoc style c-style-alist)))
  2038.     (if s
  2039.     (setcdr s (copy-alist descrip))    ; replace
  2040.       (setq c-style-alist (cons (cons style descrip) c-style-alist))))
  2041.   (and set-p (c-set-style style)))
  2042.  
  2043. (defun c-fill-paragraph (&optional arg)
  2044.   "Like \\[fill-paragraph] but handles C and C++ style comments.
  2045. If any of the current line is a comment or within a comment,
  2046. fill the comment or the paragraph of it that point is in,
  2047. preserving the comment indentation or line-starting decorations."
  2048.   (interactive "P")
  2049.   (let* (comment-start-place
  2050.      (first-line
  2051.       ;; Check for obvious entry to comment.
  2052.       (save-excursion
  2053.         (beginning-of-line)
  2054.         (skip-chars-forward " \t\n")
  2055.         (and (looking-at comment-start-skip)
  2056.          (setq comment-start-place (point))))))
  2057.     (if (and (memq major-mode '(c++-mode objc-mode))
  2058.          (save-excursion
  2059.            (beginning-of-line)
  2060.            (looking-at ".*//")))
  2061.     (let (fill-prefix
  2062.           (paragraph-start
  2063.            ;; Lines containing just a comment start or just an end
  2064.            ;; should not be filled into paragraphs they are next to.
  2065.            (concat 
  2066.         paragraph-start
  2067.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  2068.           (paragraph-separate
  2069.            (concat
  2070.         paragraph-separate
  2071.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$")))
  2072.       (save-excursion
  2073.         (beginning-of-line)
  2074.         ;; Move up to first line of this comment.
  2075.         (while (and (not (bobp))
  2076.             (looking-at "[ \t]*//"))
  2077.           (forward-line -1))
  2078.         (if (not (looking-at ".*//"))
  2079.         (forward-line 1))
  2080.         ;; Find the comment start in this line.
  2081.         (re-search-forward "[ \t]*//[ \t]*")
  2082.         ;; Set the fill-prefix to be what all lines except the first
  2083.         ;; should start with.
  2084.         (setq fill-prefix (buffer-substring (match-beginning 0)
  2085.                         (match-end 0)))
  2086.         (save-restriction
  2087.           ;; Narrow down to just the lines of this comment.
  2088.           (narrow-to-region (c-point 'bol)
  2089.                 (save-excursion
  2090.                   (forward-line 1)
  2091.                   (while (looking-at fill-prefix)
  2092.                     (forward-line 1))
  2093.                   (point)))
  2094.           (fill-paragraph arg)
  2095.           )))
  2096.       ;; else C style comments
  2097.       (if (or first-line
  2098.           ;; t if we enter a comment between start of function and
  2099.           ;; this line.
  2100.           (eq (c-in-literal) 'c)
  2101.           ;; t if this line contains a comment starter.
  2102.           (setq first-line
  2103.             (save-excursion
  2104.               (beginning-of-line)
  2105.               (prog1
  2106.               (re-search-forward comment-start-skip
  2107.                          (save-excursion (end-of-line)
  2108.                                  (point))
  2109.                          t)
  2110.             (setq comment-start-place (point))))))
  2111.       ;; Inside a comment: fill one comment paragraph.
  2112.       (let ((fill-prefix
  2113.          ;; The prefix for each line of this paragraph
  2114.          ;; is the appropriate part of the start of this line,
  2115.          ;; up to the column at which text should be indented.
  2116.          (save-excursion
  2117.            (beginning-of-line)
  2118.            (if (looking-at "[ \t]*/\\*.*\\*/")
  2119.                (progn (re-search-forward comment-start-skip)
  2120.                   (make-string (current-column) ?\ ))
  2121.              (if first-line (forward-line 1))
  2122.  
  2123.              (let ((line-width (progn (end-of-line) (current-column))))
  2124.                (beginning-of-line)
  2125.                (prog1
  2126.                (buffer-substring
  2127.                 (point)
  2128.  
  2129.                 ;; How shall we decide where the end of the
  2130.                 ;; fill-prefix is?
  2131.                 (progn
  2132.                   (beginning-of-line)
  2133.                   (skip-chars-forward " \t*" (c-point 'eol))
  2134.                   (point)))
  2135.  
  2136.              ;; If the comment is only one line followed
  2137.              ;; by a blank line, calling move-to-column
  2138.              ;; above may have added some spaces and tabs
  2139.              ;; to the end of the line; the fill-paragraph
  2140.              ;; function will then delete it and the
  2141.              ;; newline following it, so we'll lose a
  2142.              ;; blank line when we shouldn't.  So delete
  2143.              ;; anything move-to-column added to the end
  2144.              ;; of the line.  We record the line width
  2145.              ;; instead of the position of the old line
  2146.              ;; end because move-to-column might break a
  2147.              ;; tab into spaces, and the new characters
  2148.              ;; introduced there shouldn't be deleted.
  2149.  
  2150.              ;; If you can see a better way to do this,
  2151.              ;; please make the change.  This seems very
  2152.              ;; messy to me.
  2153.              (delete-region (progn (move-to-column line-width)
  2154.                            (point))
  2155.                     (progn (end-of-line) (point))))))))
  2156.  
  2157.         (paragraph-start
  2158.          ;; Lines containing just a comment start or just an end
  2159.          ;; should not be filled into paragraphs they are next to.
  2160.          (concat 
  2161.           paragraph-start
  2162.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  2163.         (paragraph-separate
  2164.          (concat
  2165.           paragraph-separate
  2166.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  2167.         (chars-to-delete 0))
  2168.         (save-restriction
  2169.           ;; Don't fill the comment together with the code
  2170.           ;; following it.  So temporarily exclude everything
  2171.           ;; before the comment start, and everything after the
  2172.           ;; line where the comment ends.  If comment-start-place
  2173.           ;; is non-nil, the comment starter is there.  Otherwise,
  2174.           ;; point is inside the comment.
  2175.           (narrow-to-region (save-excursion
  2176.                   (if comment-start-place
  2177.                       (goto-char comment-start-place)
  2178.                     (search-backward "/*"))
  2179.                   ;; Protect text before the comment
  2180.                   ;; start by excluding it.  Add
  2181.                   ;; spaces to bring back proper
  2182.                   ;; indentation of that point.
  2183.                   (let ((column (current-column)))
  2184.                     (prog1 (point)
  2185.                       (setq chars-to-delete column)
  2186.                       (insert-char ?\  column))))
  2187.                 (save-excursion
  2188.                   (if comment-start-place
  2189.                       (goto-char (+ comment-start-place 2)))
  2190.                   (search-forward "*/" nil 'move)
  2191.                   (forward-line 1)
  2192.                   (point)))
  2193.           (fill-paragraph arg)
  2194.           (save-excursion
  2195.         ;; Delete the chars we inserted to avoid clobbering
  2196.         ;; the stuff before the comment start.
  2197.         (goto-char (point-min))
  2198.         (if (> chars-to-delete 0)
  2199.             (delete-region (point) (+ (point) chars-to-delete)))
  2200.         ;; Find the comment ender (should be on last line of
  2201.         ;; buffer, given the narrowing) and don't leave it on
  2202.         ;; its own line, unless that's the style that's desired.
  2203.         (goto-char (point-max))
  2204.         (forward-line -1)
  2205.         (search-forward "*/" nil 'move)
  2206.         (beginning-of-line)
  2207.         (if (and c-hanging-comment-ender-p
  2208.              (looking-at "[ \t]*\\*/"))
  2209.             ;(delete-indentation)))))
  2210.             (let ((fill-column (+ fill-column 9999)))
  2211.               (forward-line -1)
  2212.               (fill-region-as-paragraph (point) (point-max)))))))
  2213.     ;; Outside of comments: do ordinary filling.
  2214.     (fill-paragraph arg)))))
  2215.  
  2216. ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
  2217. ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
  2218. (defun c-forward-into-nomenclature (&optional arg)
  2219.   "Move forward to end of a nomenclature section or word.
  2220. With arg, to it arg times."
  2221.   (interactive "p")
  2222.   (let ((case-fold-search nil))
  2223.     (if (> arg 0)
  2224.     (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
  2225.       (while (and (< arg 0)
  2226.           (re-search-backward
  2227.            "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
  2228.            (point-min) 0))
  2229.     (forward-char 1)
  2230.     (setq arg (1+ arg)))))
  2231.   (c-keep-region-active))
  2232.  
  2233. (defun c-backward-into-nomenclature (&optional arg)
  2234.   "Move backward to beginning of a nomenclature section or word.
  2235. With optional ARG, move that many times.  If ARG is negative, move
  2236. forward."
  2237.   (interactive "p")
  2238.   (c-forward-into-nomenclature (- arg))
  2239.   (c-keep-region-active))
  2240.  
  2241. (defun c-scope-operator ()
  2242.   "Insert a double colon scope operator at point.
  2243. No indentation or other \"electric\" behavior is performed."
  2244.   (interactive)
  2245.   (insert "::"))
  2246.  
  2247.  
  2248. (defun c-beginning-of-statement (&optional count lim)
  2249.   "Go to the beginning of the innermost C statement.
  2250. With prefix arg, go back N - 1 statements.  If already at the
  2251. beginning of a statement then go to the beginning of the preceding
  2252. one.  If within a string or comment, or next to a comment (only
  2253. whitespace between), move by sentences instead of statements.
  2254.  
  2255. When called from a program, this function takes 2 optional args: the
  2256. prefix arg, and a buffer position limit which is the farthest back to
  2257. search."
  2258.   (interactive "p")
  2259.   (let ((here (point))
  2260.     (count (or count 1))
  2261.     (lim (or lim (c-point 'bod)))
  2262.     state)
  2263.     (save-excursion
  2264.       (goto-char lim)
  2265.       (setq state (parse-partial-sexp (point) here nil nil)))
  2266.     (if (and (interactive-p)
  2267.          (or (nth 3 state)
  2268.          (nth 4 state)
  2269.          (looking-at (concat "[ \t]*" comment-start-skip))
  2270.          (save-excursion
  2271.            (skip-chars-backward " \t")
  2272.            (goto-char (- (point) 2))
  2273.            (looking-at "\\*/"))))
  2274.     (forward-sentence (- count))
  2275.       (while (> count 0)
  2276.     (c-beginning-of-statement-1 lim)
  2277.     (setq count (1- count)))
  2278.       (while (< count 0)
  2279.     (c-end-of-statement-1)
  2280.     (setq count (1+ count))))
  2281.     ;; its possible we've been left up-buf of lim
  2282.     (goto-char (max (point) lim))
  2283.     )
  2284.   (c-keep-region-active))
  2285.  
  2286. (defun c-end-of-statement (&optional count lim)
  2287.   "Go to the end of the innermost C statement.
  2288.  
  2289. With prefix arg, go forward N - 1 statements.  Move forward to end of
  2290. the next statement if already at end.  If within a string or comment,
  2291. move by sentences instead of statements.
  2292.  
  2293. When called from a program, this function takes 2 optional args: the
  2294. prefix arg, and a buffer position limit which is the farthest back to
  2295. search."
  2296.   (interactive "p")
  2297.   (c-beginning-of-statement (- (or count 1)) lim)
  2298.   (c-keep-region-active))
  2299.  
  2300.  
  2301. (defun c-beginning-of-statement-1 (&optional lim)
  2302.   ;; move to the start of the current statement, or the previous
  2303.   ;; statement if already at the beginning of one.
  2304.   (let ((firstp t)
  2305.     (substmt-p t)
  2306.     donep c-in-literal-cache
  2307.     ;; KLUDGE ALERT: maybe-labelp is used to pass information
  2308.     ;; between c-crosses-statement-barrier-p and
  2309.     ;; c-beginning-of-statement-1.  A better way should be
  2310.     ;; implemented.
  2311.     maybe-labelp
  2312.     (last-begin (point)))
  2313.     (while (not donep)
  2314.       ;; stop at beginning of buffer
  2315.       (if (bobp) (setq donep t)
  2316.     ;; go backwards one balanced expression, but be careful of
  2317.     ;; unbalanced paren being reached
  2318.     (if (not (c-safe (progn (backward-sexp 1) t)))
  2319.         (progn
  2320.           (if firstp
  2321.           (backward-up-list 1)
  2322.         (goto-char last-begin))
  2323.           ;; skip over any unary operators, or other special
  2324.           ;; characters appearing at front of identifier
  2325.           (save-excursion
  2326.         (c-backward-syntactic-ws lim)
  2327.         (skip-chars-backward "-+!*&:.~ \t\n")
  2328.         (if (= (preceding-char) ?\()
  2329.             (setq last-begin (point))))
  2330.           (goto-char last-begin)
  2331.           (setq last-begin (point)
  2332.             donep t)))
  2333.  
  2334.     (setq maybe-labelp nil)
  2335.     ;; see if we're in a literal. if not, then this bufpos may be
  2336.     ;; a candidate for stopping
  2337.     (cond
  2338.      ;; CASE 0: did we hit the error condition above?
  2339.      (donep)
  2340.      ;; CASE 1: are we in a literal?
  2341.      ((eq (c-in-literal lim) 'pound)
  2342.       (beginning-of-line))
  2343.      ;; CASE 2: some other kind of literal?
  2344.      ((c-in-literal lim))
  2345.      ;; CASE 3: are we looking at a conditional keyword?
  2346.      ((or (looking-at c-conditional-key)
  2347.           (and (= (following-char) ?\()
  2348.            (save-excursion
  2349.              (forward-sexp 1)
  2350.              (c-forward-syntactic-ws)
  2351.              (/= (following-char) ?\;))
  2352.            (let ((here (point))
  2353.              (foundp (progn
  2354.                    (c-backward-syntactic-ws lim)
  2355.                    (forward-word -1)
  2356.                    (and lim
  2357.                     (<= lim (point))
  2358.                     (not (c-in-literal lim))
  2359.                     (looking-at c-conditional-key)))))
  2360.              ;; did we find a conditional?
  2361.              (if (not foundp)
  2362.              (goto-char here))
  2363.              foundp)))
  2364.       ;; are we in the middle of an else-if clause?
  2365.       (if (save-excursion
  2366.         (and (not substmt-p)
  2367.              (c-safe (progn (forward-sexp -1) t))
  2368.              (looking-at "\\<else\\>[ \t\n]+\\<if\\>")
  2369.              (not (c-in-literal lim))))
  2370.           (progn
  2371.         (forward-sexp -1)
  2372.         (c-backward-to-start-of-if lim)))
  2373.       ;; are we sitting at an else clause, that we are not a
  2374.       ;; substatement of?
  2375.       (if (and (not substmt-p)
  2376.            (looking-at "\\<else\\>[^_]"))
  2377.           (c-backward-to-start-of-if lim))
  2378.       ;; are we sitting at the while of a do-while?
  2379.       (if (and (looking-at "\\<while\\>[^_]")
  2380.            (c-backward-to-start-of-do lim))
  2381.           (setq substmt-p nil))
  2382.       (setq last-begin (point)
  2383.         donep substmt-p))
  2384.      ;; CASE 4: are we looking at a label?
  2385.      ((looking-at c-label-key))
  2386.      ;; CASE 5: is this the first time we're checking?
  2387.      (firstp (setq firstp nil
  2388.                substmt-p (not (c-crosses-statement-barrier-p
  2389.                        (point) last-begin))
  2390.                last-begin (point)))
  2391.      ;; CASE 6: have we crossed a statement barrier?
  2392.      ((c-crosses-statement-barrier-p (point) last-begin)
  2393.       (setq donep t))
  2394.      ;; CASE 7: ignore labels
  2395.      ((and maybe-labelp
  2396.            (or (and c-access-key (looking-at c-access-key))
  2397.            ;; with switch labels, we have to go back further
  2398.            ;; to try to pick up the case or default
  2399.            ;; keyword. Potential bogosity alert: we assume
  2400.            ;; `case' or `default' is first thing on line
  2401.            (let ((here (point)))
  2402.              (beginning-of-line)
  2403.              (c-forward-syntactic-ws)
  2404.              (if (looking-at c-switch-label-key)
  2405.              t
  2406.                (goto-char here)
  2407.                nil))
  2408.            (looking-at c-label-key))))
  2409.      ;; CASE 8: ObjC method def
  2410.      ((and (eq major-mode 'objc-mode)
  2411.            (setq last-begin (c-in-objc-method-def-p)))
  2412.       (setq donep t))
  2413.      ;; CASE 9: nothing special
  2414.      (t (setq last-begin (point)))
  2415.      )))
  2416.     (goto-char last-begin)
  2417.     ;; we always do want to skip over non-whitespace modifier
  2418.     ;; characters that didn't get skipped above
  2419.     (skip-chars-backward "-+!*&:.~" (c-point 'boi))))
  2420.  
  2421. (defun c-end-of-statement-1 ()
  2422.   (condition-case ()
  2423.       (progn
  2424.     (while (and (not (eobp))
  2425.             (let ((beg (point)))
  2426.               (forward-sexp 1)
  2427.               (let ((end (point)))
  2428.             (save-excursion
  2429.               (goto-char beg)
  2430.               (not (re-search-forward "[;{}]" end t)))))))
  2431.     (re-search-backward "[;}]")
  2432.     (forward-char 1))
  2433.     (error 
  2434.      (let ((beg (point)))
  2435.        (backward-up-list -1)
  2436.        (let ((end (point)))
  2437.      (goto-char beg)
  2438.      (search-forward ";" end 'move))))))
  2439.  
  2440. (defun c-crosses-statement-barrier-p (from to)
  2441.   ;; Does buffer positions FROM to TO cross a C statement boundary?
  2442.   (let ((here (point))
  2443.     (lim from)
  2444.     crossedp)
  2445.     (condition-case ()
  2446.     (progn
  2447.       (goto-char from)
  2448.       (while (and (not crossedp)
  2449.               (< (point) to))
  2450.         (skip-chars-forward "^;{}:" to)
  2451.         (if (not (c-in-literal lim))
  2452.         (progn
  2453.           (if (memq (following-char) '(?\; ?{ ?}))
  2454.               (setq crossedp t)
  2455.             (if (= (following-char) ?:)
  2456.             (setq maybe-labelp t))
  2457.             (forward-char 1))
  2458.           (setq lim (point)))
  2459.           (forward-char 1))))
  2460.       (error (setq crossedp nil)))
  2461.     (goto-char here)
  2462.     crossedp))
  2463.  
  2464.  
  2465. (defun c-up-conditional (count)
  2466.   "Move back to the containing preprocessor conditional, leaving mark behind.
  2467. A prefix argument acts as a repeat count.  With a negative argument,
  2468. move forward to the end of the containing preprocessor conditional.
  2469. When going backwards, `#elif' is treated like `#else' followed by
  2470. `#if'.  When going forwards, `#elif' is ignored."
  2471.   (interactive "p")
  2472.   (c-forward-conditional (- count) t)
  2473.   (c-keep-region-active))
  2474.  
  2475. (defun c-backward-conditional (count &optional up-flag)
  2476.   "Move back across a preprocessor conditional, leaving mark behind.
  2477. A prefix argument acts as a repeat count.  With a negative argument,
  2478. move forward across a preprocessor conditional."
  2479.   (interactive "p")
  2480.   (c-forward-conditional (- count) up-flag)
  2481.   (c-keep-region-active))
  2482.  
  2483. (defun c-forward-conditional (count &optional up-flag)
  2484.   "Move forward across a preprocessor conditional, leaving mark behind.
  2485. A prefix argument acts as a repeat count.  With a negative argument,
  2486. move backward across a preprocessor conditional."
  2487.   (interactive "p")
  2488.   (let* ((forward (> count 0))
  2489.      (increment (if forward -1 1))
  2490.      (search-function (if forward 're-search-forward 're-search-backward))
  2491.      (new))
  2492.     (save-excursion
  2493.       (while (/= count 0)
  2494.     (let ((depth (if up-flag 0 -1)) found)
  2495.       (save-excursion
  2496.         ;; Find the "next" significant line in the proper direction.
  2497.         (while (and (not found)
  2498.             ;; Rather than searching for a # sign that
  2499.             ;; comes at the beginning of a line aside from
  2500.             ;; whitespace, search first for a string
  2501.             ;; starting with # sign.  Then verify what
  2502.             ;; precedes it.  This is faster on account of
  2503.             ;; the fastmap feature of the regexp matcher.
  2504.             (funcall search-function
  2505.                  "#[ \t]*\\(if\\|elif\\|endif\\)"
  2506.                  nil t))
  2507.           (beginning-of-line)
  2508.           ;; Now verify it is really a preproc line.
  2509.           (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
  2510.           (let ((prev depth))
  2511.             ;; Update depth according to what we found.
  2512.             (beginning-of-line)
  2513.             (cond ((looking-at "[ \t]*#[ \t]*endif")
  2514.                (setq depth (+ depth increment)))
  2515.               ((looking-at "[ \t]*#[ \t]*elif")
  2516.                (if (and forward (= depth 0))
  2517.                    (setq found (point))))
  2518.               (t (setq depth (- depth increment))))
  2519.             ;; If we are trying to move across, and we find an
  2520.             ;; end before we find a beginning, get an error.
  2521.             (if (and (< prev 0) (< depth prev))
  2522.             (error (if forward
  2523.                    "No following conditional at this level"
  2524.                  "No previous conditional at this level")))
  2525.             ;; When searching forward, start from next line so
  2526.             ;; that we don't find the same line again.
  2527.             (if forward (forward-line 1))
  2528.             ;; If this line exits a level of conditional, exit
  2529.             ;; inner loop.
  2530.             (if (< depth 0)
  2531.             (setq found (point))))
  2532.         ;; else
  2533.         (if forward (forward-line 1))
  2534.         )))
  2535.       (or found
  2536.           (error "No containing preprocessor conditional"))
  2537.       (goto-char (setq new found)))
  2538.     (setq count (+ count increment))))
  2539.     (push-mark)
  2540.     (goto-char new))
  2541.   (c-keep-region-active))
  2542.  
  2543.  
  2544. ;; commands to indent lines, regions, defuns, and expressions
  2545. (defun c-indent-command (&optional whole-exp)
  2546.   "Indent current line as C++ code, or in some cases insert a tab character.
  2547.  
  2548. If `c-tab-always-indent' is t, always just indent the current line.
  2549. If nil, indent the current line only if point is at the left margin or
  2550. in the line's indentation; otherwise insert a tab.  If other than nil
  2551. or t, then tab is inserted only within literals (comments and strings)
  2552. and inside preprocessor directives, but line is always reindented.
  2553.  
  2554. A numeric argument, regardless of its value, means indent rigidly all
  2555. the lines of the expression starting after point so that this line
  2556. becomes properly indented.  The relative indentation among the lines
  2557. of the expression are preserved."
  2558.   (interactive "P")
  2559.   (let ((bod (c-point 'bod)))
  2560.     (if whole-exp
  2561.     ;; If arg, always indent this line as C
  2562.     ;; and shift remaining lines of expression the same amount.
  2563.     (let ((shift-amt (c-indent-line))
  2564.           beg end)
  2565.       (save-excursion
  2566.         (if (eq c-tab-always-indent t)
  2567.         (beginning-of-line))
  2568.         (setq beg (point))
  2569.         (forward-sexp 1)
  2570.         (setq end (point))
  2571.         (goto-char beg)
  2572.         (forward-line 1)
  2573.         (setq beg (point)))
  2574.       (if (> end beg)
  2575.           (indent-code-rigidly beg end (- shift-amt) "#")))
  2576.       ;; No arg supplied, use c-tab-always-indent to determine
  2577.       ;; behavior
  2578.       (cond
  2579.        ;; CASE 1: indent when at column zero or in lines indentation,
  2580.        ;; otherwise insert a tab
  2581.        ((not c-tab-always-indent)
  2582.     (if (save-excursion
  2583.           (skip-chars-backward " \t")
  2584.           (not (bolp)))
  2585.         (insert-tab)
  2586.       (c-indent-line)))
  2587.        ;; CASE 2: just indent the line
  2588.        ((eq c-tab-always-indent t)
  2589.     (c-indent-line))
  2590.        ;; CASE 3: if in a literal, insert a tab, but always indent the
  2591.        ;; line
  2592.        (t
  2593.     (if (c-in-literal bod)
  2594.         (insert-tab))
  2595.     (c-indent-line)
  2596.     )))))
  2597.  
  2598. (defun c-indent-exp (&optional shutup-p)
  2599.   "Indent each line in balanced expression following point.
  2600. Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
  2601.   (interactive "P")
  2602.   (let ((here (point))
  2603.     end progress-p)
  2604.     (unwind-protect
  2605.     (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
  2606.           (start (progn
  2607.                ;; try to be smarter about finding the range of
  2608.                ;; lines to indent. skip all following
  2609.                ;; whitespace. failing that, try to find any
  2610.                ;; opening brace on the current line
  2611.                (skip-chars-forward " \t\n")
  2612.                (if (memq (following-char) '(?\( ?\[ ?\{))
  2613.                (point)
  2614.              (let ((state (parse-partial-sexp (point)
  2615.                               (c-point 'eol))))
  2616.                (and (nth 1 state)
  2617.                 (goto-char (nth 1 state))
  2618.                 (memq (following-char) '(?\( ?\[ ?\{))
  2619.                 (point)))))))
  2620.       ;; find balanced expression end
  2621.       (setq end (and (c-safe (progn (forward-sexp 1) t))
  2622.              (point-marker)))
  2623.       ;; sanity check
  2624.       (and (not start)
  2625.            (not shutup-p)
  2626.            (error "Cannot find start of balanced expression to indent."))
  2627.       (and (not end)
  2628.            (not shutup-p)
  2629.            (error "Cannot find end of balanced expression to indent."))
  2630.       (c-progress-init start end 'c-indent-exp)
  2631.       (setq progress-p t)
  2632.       (goto-char start)
  2633.       (beginning-of-line)
  2634.       (while (< (point) end)
  2635.         (if (not (looking-at "[ \t]*$"))
  2636.         (c-indent-line))
  2637.         (c-progress-update)
  2638.         (forward-line 1)))
  2639.       ;; make sure marker is deleted
  2640.       (and end
  2641.        (set-marker end nil))
  2642.       (and progress-p
  2643.        (c-progress-fini 'c-indent-exp))
  2644.       (goto-char here))))
  2645.  
  2646. (defun c-indent-defun ()
  2647.   "Re-indents the current top-level function def, struct or class declaration."
  2648.   (interactive)
  2649.   (let ((here (point-marker))
  2650.     (c-echo-syntactic-information-p nil)
  2651.     (brace (c-least-enclosing-brace (c-parse-state))))
  2652.     (if brace
  2653.     (goto-char brace)
  2654.       (beginning-of-defun))
  2655.     ;; if we're sitting at b-o-b, it might be becase there was no
  2656.     ;; least enclosing brace and we were sitting on the defun's open
  2657.     ;; brace.
  2658.     (if (and (bobp) (not (= (following-char) ?\{)))
  2659.     (goto-char here))
  2660.     ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
  2661.     ;; the open brace. I consider this an Emacs bug.
  2662.     (and (boundp 'defun-prompt-regexp)
  2663.      defun-prompt-regexp
  2664.      (looking-at defun-prompt-regexp)
  2665.      (goto-char (match-end 0)))
  2666.     ;; catch all errors in c-indent-exp so we can 1. give more
  2667.     ;; meaningful error message, and 2. restore point
  2668.     (unwind-protect
  2669.     (c-indent-exp)
  2670.       (goto-char here)
  2671.       (set-marker here nil))))
  2672.  
  2673. (defun c-indent-region (start end)
  2674.   ;; Indent every line whose first char is between START and END inclusive.
  2675.   (save-excursion
  2676.     (goto-char start)
  2677.     ;; Advance to first nonblank line.
  2678.     (skip-chars-forward " \t\n")
  2679.     (beginning-of-line)
  2680.     (let (endmark)
  2681.       (unwind-protect
  2682.       (let ((c-tab-always-indent t)
  2683.         ;; shut up any echo msgs on indiv lines
  2684.         (c-echo-syntactic-information-p nil))
  2685.         (c-progress-init start end 'c-indent-region)
  2686.         (setq endmark (copy-marker end))
  2687.         (while (and (bolp)
  2688.             (not (eobp))
  2689.             (< (point) endmark))
  2690.           ;; update progress
  2691.           (c-progress-update)
  2692.           ;; Indent one line as with TAB.
  2693.           (let (nextline sexpend sexpbeg)
  2694.         ;; skip blank lines
  2695.         (skip-chars-forward " \t\n")
  2696.         (beginning-of-line)
  2697.         ;; indent the current line
  2698.         (c-indent-line)
  2699.         (if (save-excursion
  2700.               (beginning-of-line)
  2701.               (looking-at "[ \t]*#"))
  2702.             (forward-line 1)
  2703.           (save-excursion
  2704.             ;; Find beginning of following line.
  2705.             (setq nextline (c-point 'bonl))
  2706.             ;; Find first beginning-of-sexp for sexp extending past
  2707.             ;; this line.
  2708.             (beginning-of-line)
  2709.             (while (< (point) nextline)
  2710.               (condition-case nil
  2711.               (progn
  2712.                 (forward-sexp 1)
  2713.                 (setq sexpend (point)))
  2714.             (error (setq sexpend nil)
  2715.                    (goto-char nextline)))
  2716.               (c-forward-syntactic-ws))
  2717.             (if sexpend
  2718.             (progn 
  2719.               ;; make sure the sexp we found really starts on the
  2720.               ;; current line and extends past it
  2721.               (goto-char sexpend)
  2722.               (setq sexpend (point-marker))
  2723.               (c-safe (backward-sexp 1))
  2724.               (setq sexpbeg (point)))))
  2725.           ;; check to see if the next line starts a
  2726.           ;; comment-only line
  2727.           (save-excursion
  2728.             (forward-line 1)
  2729.             (skip-chars-forward " \t")
  2730.             (if (looking-at c-comment-start-regexp)
  2731.             (setq sexpbeg (c-point 'bol))))
  2732.           ;; If that sexp ends within the region, indent it all at
  2733.           ;; once, fast.
  2734.           (condition-case nil
  2735.               (if (and sexpend
  2736.                    (> sexpend nextline)
  2737.                    (<= sexpend endmark))
  2738.               (progn
  2739.                 (goto-char sexpbeg)
  2740.                 (c-indent-exp 'shutup)
  2741.                 (c-progress-update)
  2742.                 (goto-char sexpend)))
  2743.             (error
  2744.              (goto-char sexpbeg)
  2745.              (c-indent-line)))
  2746.           ;; Move to following line and try again.
  2747.           (and sexpend
  2748.                (markerp sexpend)
  2749.                (set-marker sexpend nil))
  2750.           (forward-line 1)))))
  2751.     (set-marker endmark nil)
  2752.     (c-progress-fini 'c-indent-region)
  2753.     ))))
  2754.  
  2755. (defun c-mark-function ()
  2756.   "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
  2757.   (interactive)
  2758.   (let ((here (point))
  2759.     ;; there should be a c-point position for 'eod
  2760.     (eod  (save-excursion (end-of-defun) (point)))
  2761.     (state (c-parse-state))
  2762.     brace)
  2763.     (while state
  2764.       (setq brace (car state))
  2765.       (if (consp brace)
  2766.       (goto-char (cdr brace))
  2767.     (goto-char brace))
  2768.       (setq state (cdr state)))
  2769.     (if (= (following-char) ?{)
  2770.     (progn
  2771.       (forward-line -1)
  2772.       (while (not (or (bobp)
  2773.               (looking-at "[ \t]*$")))
  2774.         (forward-line -1)))
  2775.       (forward-line 1)
  2776.       (skip-chars-forward " \t\n"))
  2777.     (push-mark here)
  2778.     (push-mark eod nil t)))
  2779.  
  2780.  
  2781. ;; for progress reporting
  2782. (defvar c-progress-info nil)
  2783.  
  2784. (defun c-progress-init (start end context)
  2785.   ;; start the progress update messages.  if this emacs doesn't have a
  2786.   ;; built-in timer, just be dumb about it
  2787.   (if (not (fboundp 'current-time))
  2788.       (message "indenting region... (this may take a while)")
  2789.     ;; if progress has already been initialized, do nothing. otherwise
  2790.     ;; initialize the counter with a vector of:
  2791.     ;; [start end lastsec context]
  2792.     (if c-progress-info
  2793.     ()
  2794.       (setq c-progress-info (vector start
  2795.                     (save-excursion
  2796.                       (goto-char end)
  2797.                       (point-marker))
  2798.                     (nth 1 (current-time))
  2799.                     context))
  2800.       (message "indenting region..."))))
  2801.  
  2802. (defun c-progress-update ()
  2803.   ;; update progress
  2804.   (if (not (and c-progress-info c-progress-interval))
  2805.       nil
  2806.     (let ((now (nth 1 (current-time)))
  2807.       (start (aref c-progress-info 0))
  2808.       (end (aref c-progress-info 1))
  2809.       (lastsecs (aref c-progress-info 2)))
  2810.       ;; should we update?  currently, update happens every 2 seconds,
  2811.       ;; what's the right value?
  2812.       (if (< c-progress-interval (- now lastsecs))
  2813.       (progn
  2814.         (message "indenting region... (%d%% complete)"
  2815.              (/ (* 100 (- (point) start)) (- end start)))
  2816.         (aset c-progress-info 2 now)))
  2817.       )))
  2818.  
  2819. (defun c-progress-fini (context)
  2820.   ;; finished
  2821.   (if (or (eq context (aref c-progress-info 3))
  2822.       (eq context t))
  2823.       (progn
  2824.     (set-marker (aref c-progress-info 1) nil)
  2825.     (setq c-progress-info nil)
  2826.     (message "indenting region... done."))))
  2827.  
  2828.  
  2829. ;; Skipping of "syntactic whitespace" for Emacs 19.  Syntactic
  2830. ;; whitespace is defined as lexical whitespace, C and C++ style
  2831. ;; comments, and preprocessor directives.  Search no farther back or
  2832. ;; forward than optional LIM.  If LIM is omitted, `beginning-of-defun'
  2833. ;; is used for backward skipping, point-max is used for forward
  2834. ;; skipping.  Note that Emacs 18 support has been moved to cc-mode-18.el.
  2835.  
  2836. (defun c-forward-syntactic-ws (&optional lim)
  2837.   ;; Forward skip of syntactic whitespace for Emacs 19.
  2838.   (save-restriction
  2839.     (let* ((lim (or lim (point-max)))
  2840.        (here lim)
  2841.        (hugenum (point-max)))
  2842.       (narrow-to-region lim (point))
  2843.       (while (/= here (point))
  2844.     (setq here (point))
  2845.     (forward-comment hugenum)
  2846.     ;; skip preprocessor directives
  2847.     (if (and (= (following-char) ?#)
  2848.          (= (c-point 'boi) (point)))
  2849.         (end-of-line)
  2850.       )))))
  2851.  
  2852. (defun c-backward-syntactic-ws (&optional lim)
  2853.   ;; Backward skip over syntactic whitespace for Emacs 19.
  2854.   (save-restriction
  2855.     (let* ((lim (or lim (c-point 'bod)))
  2856.        (here lim)
  2857.        (hugenum (- (point-max))))
  2858.       (if (< lim (point))
  2859.       (progn
  2860.         (narrow-to-region lim (point))
  2861.         (while (/= here (point))
  2862.           (setq here (point))
  2863.           (forward-comment hugenum)
  2864.           (if (eq (c-in-literal lim) 'pound)
  2865.           (beginning-of-line))
  2866.           )))
  2867.       )))
  2868.  
  2869.  
  2870. ;; Return `c' if in a C-style comment, `c++' if in a C++ style
  2871. ;; comment, `string' if in a string literal, `pound' if on a
  2872. ;; preprocessor line, or nil if not in a comment at all.  Optional LIM
  2873. ;; is used as the backward limit of the search.  If omitted, or nil,
  2874. ;; `beginning-of-defun' is used."
  2875.  
  2876. ;; This is for all v19 Emacsen supporting either 1-bit or 8-bit syntax
  2877. (defun c-in-literal (&optional lim)
  2878.   ;; Determine if point is in a C++ literal. we cache the last point
  2879.   ;; calculated if the cache is enabled
  2880.   (if (and (boundp 'c-in-literal-cache)
  2881.        c-in-literal-cache
  2882.        (= (point) (aref c-in-literal-cache 0)))
  2883.       (aref c-in-literal-cache 1)
  2884.     (let ((rtn (save-excursion
  2885.          (let* ((lim (or lim (c-point 'bod)))
  2886.             (here (point))
  2887.             (state (parse-partial-sexp lim (point))))
  2888.            (cond
  2889.             ((nth 3 state) 'string)
  2890.             ((nth 4 state) (if (nth 7 state) 'c++ 'c))
  2891.             ((progn
  2892.                (goto-char here)
  2893.                (beginning-of-line)
  2894.                (looking-at "[ \t]*#"))
  2895.              'pound)
  2896.             (t nil))))))
  2897.       ;; cache this result if the cache is enabled
  2898.       (and (boundp 'c-in-literal-cache)
  2899.        (setq c-in-literal-cache (vector (point) rtn)))
  2900.       rtn)))
  2901.  
  2902.  
  2903. ;; utilities for moving and querying around syntactic elements
  2904. (defun c-parse-state ()
  2905.   ;; Finds and records all open parens between some important point
  2906.   ;; earlier in the file and point.
  2907.   ;;
  2908.   ;; if there's a state cache, return it
  2909.   (if (boundp 'c-state-cache) c-state-cache
  2910.     (let* (at-bob
  2911.        (pos (save-excursion
  2912.           ;; go back 2 bods, but ignore any bogus positions
  2913.           ;; returned by beginning-of-defun (i.e. open paren
  2914.           ;; in column zero)
  2915.           (let ((cnt 2))
  2916.             (while (not (or at-bob (zerop cnt)))
  2917.               (beginning-of-defun)
  2918.               (if (= (following-char) ?\{)
  2919.               (setq cnt (1- cnt)))
  2920.               (if (bobp)
  2921.               (setq at-bob t))))
  2922.           (point)))
  2923.        (here (save-excursion
  2924.            ;;(skip-chars-forward " \t}")
  2925.            (point)))
  2926.        (last-bod pos) (last-pos pos)
  2927.        placeholder state sexp-end)
  2928.       ;; cache last bod position
  2929.       (while (catch 'backup-bod
  2930.            (setq state nil)
  2931.            (while (and pos (< pos here))
  2932.          (setq last-pos pos)
  2933.          (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
  2934.               (<= pos here))
  2935.              (progn
  2936.                (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
  2937.                (if (and sexp-end
  2938.                 (<= sexp-end here))
  2939.                ;; we want to record both the start and end
  2940.                ;; of this sexp, but we only want to record
  2941.                ;; the last-most of any of them before here
  2942.                (progn
  2943.                  (if (= (char-after (1- pos)) ?\{)
  2944.                  (setq state (cons (cons (1- pos) sexp-end)
  2945.                            (if (consp (car state))
  2946.                                (cdr state)
  2947.                              state))))
  2948.                  (setq pos sexp-end))
  2949.              ;; we're contained in this sexp so put pos on
  2950.              ;; front of list
  2951.              (setq state (cons (1- pos) state))))
  2952.            ;; something bad happened. check to see if we
  2953.            ;; crossed an unbalanced close brace. if so, we
  2954.            ;; didn't really find the right `important bufpos'
  2955.            ;; so lets back up and try again
  2956.            (if (and (not pos) (not at-bob)
  2957.                 (setq placeholder
  2958.                   (c-safe (scan-lists last-pos 1 1)))
  2959.                 ;;(char-after (1- placeholder))
  2960.                 (<= placeholder here)
  2961.                 (= (char-after (1- placeholder)) ?\}))
  2962.                (while t
  2963.              (setq last-bod (c-safe (scan-lists last-bod -1 1)))
  2964.              (if (not last-bod)
  2965.                  (error "unbalanced close brace at position %d"
  2966.                     (1- placeholder))
  2967.                (setq at-bob (= last-bod (point-min))
  2968.                  pos last-bod)
  2969.                (if (= (char-after last-bod) ?\{)
  2970.                    (throw 'backup-bod t)))
  2971.              ))        ;end-if
  2972.            ))            ;end-while
  2973.            nil))
  2974.       state)))
  2975.  
  2976. (defun c-whack-state (bufpos state)
  2977.   ;; whack off any state information that appears on STATE which lies
  2978.   ;; after the bounds of BUFPOS.
  2979.   (let (newstate car)
  2980.     (while state
  2981.       (setq car (car state)
  2982.         state (cdr state))
  2983.       (if (consp car)
  2984.       ;; just check the car, because in a balanced brace
  2985.       ;; expression, it must be impossible for the corresponding
  2986.       ;; close brace to be before point, but the open brace to be
  2987.       ;; after.
  2988.       (if (<= bufpos (car car))
  2989.           nil            ; whack it off
  2990.         ;; its possible that the open brace is before bufpos, but
  2991.         ;; the close brace is after.  In that case, convert this
  2992.         ;; to a non-cons element.
  2993.         (if (<= bufpos (cdr car))
  2994.         (setq newstate (append newstate (list (car car))))
  2995.           ;; we know that both the open and close braces are
  2996.           ;; before bufpos, so we also know that everything else
  2997.           ;; on state is before bufpos, so we can glom up the
  2998.           ;; whole thing and exit.
  2999.           (setq newstate (append newstate (list car) state)
  3000.             state nil)))
  3001.     (if (<= bufpos car)
  3002.         nil                ; whack it off
  3003.       ;; it's before bufpos, so everything else should too
  3004.       (setq newstate (append newstate (list car) state)
  3005.         state nil))))
  3006.     newstate))
  3007.  
  3008. (defun c-hack-state (bufpos which state)
  3009.   ;; Using BUFPOS buffer position, and WHICH (must be 'open or
  3010.   ;; 'close), hack the c-parse-state STATE and return the results.
  3011.   (if (eq which 'open)
  3012.       (let ((car (car state)))
  3013.     (if (or (null car)
  3014.         (consp car)
  3015.         (/= bufpos car))
  3016.         (cons bufpos state)
  3017.       state))
  3018.     (if (not (eq which 'close))
  3019.     (error "c-hack-state, bad argument: %s" which))
  3020.     ;; 'close brace
  3021.     (let ((car (car state))
  3022.       (cdr (cdr state)))
  3023.       (if (consp car)
  3024.       (setq car (car cdr)
  3025.         cdr (cdr cdr)))
  3026.       ;; TBD: is this test relevent???
  3027.       (if (consp car)
  3028.       state                ;on error, don't change
  3029.     ;; watch out for balanced expr already on cdr of list
  3030.     (cons (cons car bufpos)
  3031.           (if (consp (car cdr))
  3032.           (cdr cdr) cdr))
  3033.     ))))
  3034.  
  3035. (defun c-adjust-state (from to shift state)
  3036.   ;; Adjust all points in state that lie in the region FROM..TO by
  3037.   ;; SHIFT amount (as would be returned by c-indent-line).
  3038.   (mapcar
  3039.    (function
  3040.     (lambda (e)
  3041.       (if (consp e)
  3042.       (let ((car (car e))
  3043.         (cdr (cdr e)))
  3044.         (if (and (<= from car) (< car to))
  3045.         (setcar e (+ shift car)))
  3046.         (if (and (<= from cdr) (< cdr to))
  3047.         (setcdr e (+ shift cdr))))
  3048.     (if (and (<= from e) (< e to))
  3049.         (setq e (+ shift e))))
  3050.       e))
  3051.    state))
  3052.  
  3053.  
  3054. (defun c-beginning-of-inheritance-list (&optional lim)
  3055.   ;; Go to the first non-whitespace after the colon that starts a
  3056.   ;; multiple inheritance introduction.  Optional LIM is the farthest
  3057.   ;; back we should search.
  3058.   (let ((lim (or lim (c-point 'bod)))
  3059.     (placeholder (progn
  3060.                (back-to-indentation)
  3061.                (point))))
  3062.     (c-backward-syntactic-ws lim)
  3063.     (while (and (> (point) lim)
  3064.         (memq (preceding-char) '(?, ?:))
  3065.         (progn
  3066.           (beginning-of-line)
  3067.           (setq placeholder (point))
  3068.           (skip-chars-forward " \t")
  3069.           (not (looking-at c-class-key))
  3070.           ))
  3071.       (c-backward-syntactic-ws lim))
  3072.     (goto-char placeholder)
  3073.     (skip-chars-forward "^:" (c-point 'eol))))
  3074.  
  3075. (defun c-beginning-of-macro (&optional lim)
  3076.   ;; Go to the beginning of the macro. Right now we don't support
  3077.   ;; multi-line macros too well
  3078.   (back-to-indentation))
  3079.  
  3080. (defun c-in-objc-method-def-p ()
  3081.   ;; Return nil if we aren't in a method definition, otherwise the
  3082.   ;; position of the initial [+-].
  3083.   (save-excursion
  3084.     (beginning-of-line)
  3085.     (if (looking-at c-ObjC-method-key)
  3086.         (point)
  3087.       nil)))
  3088.  
  3089. (defun c-just-after-func-arglist-p (&optional containing)
  3090.   ;; Return t if we are between a function's argument list closing
  3091.   ;; paren and its opening brace.  Note that the list close brace
  3092.   ;; could be followed by a "const" specifier or a member init hanging
  3093.   ;; colon.  Optional CONTAINING is position of containing s-exp open
  3094.   ;; brace.  If not supplied, point is used as search start.
  3095.   (save-excursion
  3096.     (c-backward-syntactic-ws)
  3097.     (let ((checkpoint (or containing (point))))
  3098.       (goto-char checkpoint)
  3099.       ;; could be looking at const specifier
  3100.       (if (and (= (preceding-char) ?t)
  3101.            (forward-word -1)
  3102.            (looking-at "\\<const\\>"))
  3103.       (c-backward-syntactic-ws)
  3104.     ;; otherwise, we could be looking at a hanging member init
  3105.     ;; colon
  3106.     (goto-char checkpoint)
  3107.     (if (and (= (preceding-char) ?:)
  3108.          (progn
  3109.            (forward-char -1)
  3110.            (c-backward-syntactic-ws)
  3111.            (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
  3112.         nil
  3113.       (goto-char checkpoint))
  3114.     )
  3115.       (and (= (preceding-char) ?\))
  3116.        ;; check if we are looking at a method def
  3117.        (or (not (eq major-mode 'objc-mode))
  3118.            (progn
  3119.          (forward-sexp -1)
  3120.          (forward-char -1)
  3121.          (c-backward-syntactic-ws)
  3122.          (not (or (= (preceding-char) ?-)
  3123.               (= (preceding-char) ?+)
  3124.               ;; or a class category
  3125.               (progn
  3126.                 (forward-sexp -2)
  3127.                 (looking-at c-class-key))
  3128.               )))))
  3129.       )))
  3130.  
  3131. ;; defuns to look backwards for things
  3132. (defun c-backward-to-start-of-do (&optional lim)
  3133.   ;; Move to the start of the last "unbalanced" do expression.
  3134.   ;; Optional LIM is the farthest back to search.  If none is found,
  3135.   ;; nil is returned and point is left unchanged, otherwise t is returned.
  3136.   (let ((do-level 1)
  3137.     (case-fold-search nil)
  3138.     (lim (or lim (c-point 'bod)))
  3139.     (here (point))
  3140.     foundp)
  3141.     (while (not (zerop do-level))
  3142.       ;; we protect this call because trying to execute this when the
  3143.       ;; while is not associated with a do will throw an error
  3144.       (condition-case nil
  3145.       (progn
  3146.         (backward-sexp 1)
  3147.         (cond
  3148.          ((memq (c-in-literal lim) '(c c++)))
  3149.          ((looking-at "while\\b[^_]")
  3150.           (setq do-level (1+ do-level)))
  3151.          ((looking-at "do\\b[^_]")
  3152.           (if (zerop (setq do-level (1- do-level)))
  3153.           (setq foundp t)))
  3154.          ((< (point) lim)
  3155.           (setq do-level 0)
  3156.           (goto-char lim))))
  3157.     (error
  3158.      (goto-char lim)
  3159.      (setq do-level 0))))
  3160.     (if (not foundp)
  3161.     (goto-char here))
  3162.     foundp))
  3163.  
  3164. (defun c-backward-to-start-of-if (&optional lim)
  3165.   ;; Move to the start of the last "unbalanced" if and return t.  If
  3166.   ;; none is found, and we are looking at an if clause, nil is
  3167.   ;; returned.  If none is found and we are looking at an else clause,
  3168.   ;; an error is thrown.
  3169.   (let ((if-level 1)
  3170.     (here (c-point 'bol))
  3171.     (case-fold-search nil)
  3172.     (lim (or lim (c-point 'bod)))
  3173.     (at-if (looking-at "if\\b[^_]")))
  3174.     (catch 'orphan-if
  3175.       (while (and (not (bobp))
  3176.           (not (zerop if-level)))
  3177.     (c-backward-syntactic-ws)
  3178.     (condition-case nil
  3179.         (backward-sexp 1)
  3180.       (error
  3181.        (if at-if
  3182.            (throw 'orphan-if nil)
  3183.          (error "No matching `if' found for `else' on line %d."
  3184.             (1+ (count-lines 1 here))))))
  3185.     (cond
  3186.      ((looking-at "else\\b[^_]")
  3187.       (setq if-level (1+ if-level)))
  3188.      ((looking-at "if\\b[^_]")
  3189.       ;; check for else if... skip over
  3190.       (let ((here (point)))
  3191.         (c-safe (forward-sexp -1))
  3192.         (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  3193.         nil
  3194.           (setq if-level (1- if-level))
  3195.           (goto-char here))))
  3196.      ((< (point) lim)
  3197.       (setq if-level 0)
  3198.       (goto-char lim))
  3199.      ))
  3200.       t)))
  3201.  
  3202. (defun c-skip-conditional ()
  3203.   ;; skip forward over conditional at point, including any predicate
  3204.   ;; statements in parentheses. No error checking is performed.
  3205.   (forward-sexp
  3206.    ;; else if()
  3207.    (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  3208.        3
  3209.      ;; do and else aren't followed by parens
  3210.      (if (looking-at "\\<\\(do\\|else\\)\\>")
  3211.      1 2))))
  3212.  
  3213. (defun c-skip-case-statement-forward (state &optional lim)
  3214.   ;; skip forward over case/default bodies, with optional maximal
  3215.   ;; limit. if no next case body is found, nil is returned and point
  3216.   ;; is not moved
  3217.   (let ((lim (or lim (point-max)))
  3218.     (here (point))
  3219.     donep foundp bufpos
  3220.     (safepos (point))
  3221.     (balanced (car state)))
  3222.     ;; search until we've passed the limit, or we've found our match
  3223.     (while (and (< (point) lim)
  3224.         (not donep))
  3225.       (setq safepos (point))
  3226.       ;; see if we can find a case statement, not in a literal
  3227.       (if (and (re-search-forward c-switch-label-key lim 'move)
  3228.            (setq bufpos (match-beginning 0))
  3229.            (not (c-in-literal safepos))
  3230.            (/= bufpos here))
  3231.       ;; if we crossed into a balanced sexp, we know the case is
  3232.       ;; not part of our switch statement, so just bound over the
  3233.       ;; sexp and keep looking.
  3234.       (if (and (consp balanced)
  3235.            (> bufpos (car balanced))
  3236.            (< bufpos (cdr balanced)))
  3237.           (goto-char (cdr balanced))
  3238.         (goto-char bufpos)
  3239.         (setq donep t
  3240.           foundp t))))
  3241.     (if (not foundp)
  3242.     (goto-char here))
  3243.     foundp))
  3244.  
  3245. (defun c-search-uplist-for-classkey (brace-state)
  3246.   ;; search for the containing class, returning a 2 element vector if
  3247.   ;; found. aref 0 contains the bufpos of the class key, and aref 1
  3248.   ;; contains the bufpos of the open brace.
  3249.   (if (null brace-state)
  3250.       ;; no brace-state means we cannot be inside a class
  3251.       nil
  3252.     (let ((carcache (car brace-state))
  3253.       search-start search-end)
  3254.       (if (consp carcache)
  3255.       ;; a cons cell in the first element means that there is some
  3256.       ;; balanced sexp before the current bufpos. this we can
  3257.       ;; ignore. the nth 1 and nth 2 elements define for us the
  3258.       ;; search boundaries
  3259.       (setq search-start (nth 2 brace-state)
  3260.         search-end (nth 1 brace-state))
  3261.     ;; if the car was not a cons cell then nth 0 and nth 1 define
  3262.     ;; for us the search boundaries
  3263.     (setq search-start (nth 1 brace-state)
  3264.           search-end (nth 0 brace-state)))
  3265.       ;; search-end cannot be a cons cell
  3266.       (and (consp search-end)
  3267.        (error "consp search-end: %s" search-end))
  3268.       ;; if search-end is nil, or if the search-end character isn't an
  3269.       ;; open brace, we are definitely not in a class
  3270.       (if (or (not search-end)
  3271.           (< search-end (point-min))
  3272.           (/= (char-after search-end) ?{))
  3273.       nil
  3274.     ;; now, we need to look more closely at search-start.  if
  3275.     ;; search-start is nil, then our start boundary is really
  3276.     ;; point-min.
  3277.     (if (not search-start)
  3278.         (setq search-start (point-min))
  3279.       ;; if search-start is a cons cell, then we can start
  3280.       ;; searching from the end of the balanced sexp just ahead of
  3281.       ;; us
  3282.       (if (consp search-start)
  3283.           (setq search-start (cdr search-start))))
  3284.     ;; now we can do a quick regexp search from search-start to
  3285.     ;; search-end and see if we can find a class key.  watch for
  3286.     ;; class like strings in literals
  3287.     (save-excursion
  3288.       (save-restriction
  3289.         (goto-char search-start)
  3290.         (let (foundp class match-end)
  3291.           (while (and (not foundp)
  3292.               (progn
  3293.                 (c-forward-syntactic-ws)
  3294.                 (> search-end (point)))
  3295.               (re-search-forward c-class-key search-end t))
  3296.         (setq class (match-beginning 0)
  3297.               match-end (match-end 0))
  3298.         (if (c-in-literal search-start)
  3299.             nil            ; its in a comment or string, ignore
  3300.           (goto-char class)
  3301.           (skip-chars-forward " \t\n")
  3302.           (setq foundp (vector (c-point 'boi) search-end))
  3303.           (cond
  3304.            ;; check for embedded keywords
  3305.            ((let ((char (char-after (1- class))))
  3306.               (and char
  3307.                (memq (char-syntax char) '(?w ?_))))
  3308.             (goto-char match-end)
  3309.             (setq foundp nil))
  3310.            ;; make sure we're really looking at the start of a
  3311.            ;; class definition, and not a forward decl, return
  3312.            ;; arg, template arg list, or an ObjC method.
  3313.            ((and (eq major-mode 'objc-mode)
  3314.              (re-search-forward c-ObjC-method-key search-end t))
  3315.             (setq foundp nil))
  3316.            ;; Its impossible to define a regexp for this, and
  3317.            ;; nearly so to do it programmatically.
  3318.            ;;
  3319.            ;; ; picks up forward decls
  3320.            ;; = picks up init lists
  3321.            ;; ) picks up return types
  3322.            ;; > picks up templates, but remember that we can
  3323.            ;;   inherit from templates!
  3324.            ((let ((skipchars "^;=)"))
  3325.               ;; try to see if we found the `class' keyword
  3326.               ;; inside a template arg list
  3327.               (save-excursion
  3328.             (skip-chars-backward "^<>" search-start)
  3329.             (if (= (preceding-char) ?<)
  3330.                 (setq skipchars (concat skipchars ">"))))
  3331.               (skip-chars-forward skipchars search-end)
  3332.               (/= (point) search-end))
  3333.             (setq foundp nil))
  3334.            )))
  3335.           foundp))
  3336.       )))))
  3337.  
  3338. (defun c-inside-bracelist-p (containing-sexp brace-state)
  3339.   ;; return the buffer position of the beginning of the brace list
  3340.   ;; statement if we're inside a brace list, otherwise return nil.
  3341.   ;; CONTAINING-SEXP is the buffer pos of the innermost containing
  3342.   ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
  3343.   ;;
  3344.   ;; N.B.: This algorithm can potentially get confused by cpp macros
  3345.   ;; places in inconvenient locations.  Its a trade-off we make for
  3346.   ;; speed.
  3347.   (or
  3348.    ;; this will pick up enum lists
  3349.    (condition-case ()
  3350.        (save-excursion
  3351.      (goto-char containing-sexp)
  3352.      (forward-sexp -1)
  3353.      (if (or (looking-at "enum[\t\n ]+")
  3354.          (progn (forward-sexp -1)
  3355.             (looking-at "enum[\t\n ]+")))
  3356.          (point)))
  3357.      (error nil))
  3358.    ;; this will pick up array/aggregate init lists, even if they are nested.
  3359.    (save-excursion
  3360.      (let (bufpos failedp)
  3361.        (while (and (not bufpos)
  3362.            containing-sexp)
  3363.      (if (consp containing-sexp)
  3364.          (setq containing-sexp (car brace-state)
  3365.            brace-state (cdr brace-state))
  3366.        ;; see if significant character just before brace is an equal
  3367.        (goto-char containing-sexp)
  3368.        (setq failedp nil)
  3369.        (condition-case ()
  3370.            (progn
  3371.          (forward-sexp -1)
  3372.          (forward-sexp 1)
  3373.          (c-forward-syntactic-ws containing-sexp))
  3374.          (error (setq failedp t)))
  3375.        (if (or failedp (/= (following-char) ?=))
  3376.            ;; lets see if we're nested. find the most nested
  3377.            ;; containing brace
  3378.            (setq containing-sexp (car brace-state)
  3379.              brace-state (cdr brace-state))
  3380.          ;; we've hit the beginning of the aggregate list
  3381.          (c-beginning-of-statement-1 (c-most-enclosing-brace brace-state))
  3382.          (setq bufpos (point)))
  3383.        ))
  3384.        bufpos))
  3385.    ))
  3386.  
  3387.  
  3388. ;; defuns for calculating the syntactic state and indenting a single
  3389. ;; line of C/C++/ObjC code
  3390. (defmacro c-add-syntax (symbol &optional relpos)
  3391.   ;; a simple macro to append the syntax in symbol to the syntax list.
  3392.   ;; try to increase performance by using this macro
  3393.   (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
  3394.  
  3395. (defun c-most-enclosing-brace (state)
  3396.   ;; return the bufpos of the most enclosing brace that hasn't been
  3397.   ;; narrowed out by any enclosing class, or nil if none was found
  3398.   (let (enclosingp)
  3399.     (while (and state (not enclosingp))
  3400.       (setq enclosingp (car state)
  3401.         state (cdr state))
  3402.       (if (consp enclosingp)
  3403.       (setq enclosingp nil)
  3404.     (if (> (point-min) enclosingp)
  3405.         (setq enclosingp nil))
  3406.     (setq state nil)))
  3407.     enclosingp))
  3408.  
  3409. (defun c-least-enclosing-brace (state)
  3410.   ;; return the bufpos of the least (highest) enclosing brace that
  3411.   ;; hasn't been narrowed out by any enclosing class, or nil if none
  3412.   ;; was found.
  3413.   (c-most-enclosing-brace (nreverse state)))
  3414.  
  3415. (defun c-safe-position (bufpos state)
  3416.   ;; return the closest known safe position higher up than point
  3417.   (let ((safepos nil))
  3418.     (while state
  3419.       (setq safepos
  3420.         (if (consp (car state))
  3421.         (cdr (car state))
  3422.           (car state)))
  3423.       (if (< safepos bufpos)
  3424.       (setq state nil)
  3425.     (setq state (cdr state))))
  3426.     safepos))
  3427.  
  3428. (defun c-narrow-out-enclosing-class (state lim)
  3429.   ;; narrow the buffer so that the enclosing class is hidden
  3430.   (let (inclass-p)
  3431.     (and state
  3432.      (setq inclass-p (c-search-uplist-for-classkey state))
  3433.      (narrow-to-region
  3434.       (progn
  3435.         (goto-char (1+ (aref inclass-p 1)))
  3436.         (skip-chars-forward " \t\n" lim)
  3437.         ;; if point is now left of the class opening brace, we're
  3438.         ;; hosed, so try a different tact
  3439.         (if (<= (point) (aref inclass-p 1))
  3440.         (progn
  3441.           (goto-char (1+ (aref inclass-p 1)))
  3442.           (c-forward-syntactic-ws lim)))
  3443.         (point))
  3444.       ;; end point is the end of the current line
  3445.       (progn
  3446.         (goto-char lim)
  3447.         (c-point 'eol))))
  3448.     ;; return the class vector
  3449.     inclass-p))
  3450.  
  3451. (defun c-guess-basic-syntax ()
  3452.   ;; guess the syntactic description of the current line of C++ code.
  3453.   (save-excursion
  3454.     (save-restriction
  3455.       (beginning-of-line)
  3456.       (let* ((indent-point (point))
  3457.          (case-fold-search nil)
  3458.          (fullstate (c-parse-state))
  3459.          (state fullstate)
  3460.          (in-method-intro-p (and (eq major-mode 'objc-mode)
  3461.                      (looking-at c-ObjC-method-key)))
  3462.          literal containing-sexp char-before-ip char-after-ip lim
  3463.          syntax placeholder c-in-literal-cache inswitch-p
  3464.          ;; narrow out any enclosing class
  3465.          (inclass-p (c-narrow-out-enclosing-class state indent-point))
  3466.          )
  3467.  
  3468.     ;; get the buffer position of the most nested opening brace,
  3469.     ;; if there is one, and it hasn't been narrowed out
  3470.     (save-excursion
  3471.       (goto-char indent-point)
  3472.       (skip-chars-forward " \t}")
  3473.       (skip-chars-backward " \t")
  3474.       (while (and state
  3475.               (not in-method-intro-p)
  3476.               (not containing-sexp))
  3477.         (setq containing-sexp (car state)
  3478.           state (cdr state))
  3479.         (if (consp containing-sexp)
  3480.         ;; if cdr == point, then containing sexp is the brace
  3481.         ;; that opens the sexp we close
  3482.         (if (= (cdr containing-sexp) (point))
  3483.             (setq containing-sexp (car containing-sexp))
  3484.           ;; otherwise, ignore this element
  3485.           (setq containing-sexp nil))
  3486.           ;; ignore the bufpos if its been narrowed out by the
  3487.           ;; containing class
  3488.           (if (<= containing-sexp (point-min))
  3489.           (setq containing-sexp nil)))))
  3490.  
  3491.     ;; set the limit on the farthest back we need to search
  3492.     (setq lim (or containing-sexp
  3493.               (if (consp (car fullstate))
  3494.               (cdr (car fullstate))
  3495.             nil)
  3496.               (point-min)))
  3497.  
  3498.     ;; cache char before and after indent point, and move point to
  3499.     ;; the most likely position to perform the majority of tests
  3500.     (goto-char indent-point)
  3501.     (skip-chars-forward " \t")
  3502.     (setq char-after-ip (following-char))
  3503.     (c-backward-syntactic-ws lim)
  3504.     (setq char-before-ip (preceding-char))
  3505.     (goto-char indent-point)
  3506.     (skip-chars-forward " \t")
  3507.  
  3508.     ;; are we in a literal?
  3509.     (setq literal (c-in-literal lim))
  3510.  
  3511.     ;; now figure out syntactic qualities of the current line
  3512.     (cond
  3513.      ;; CASE 1: in a string.
  3514.      ((memq literal '(string))
  3515.       (c-add-syntax 'string (c-point 'bopl)))
  3516.      ;; CASE 2: in a C or C++ style comment.
  3517.      ((memq literal '(c c++))
  3518.       ;; we need to catch multi-paragraph C comments
  3519.       (while (and (zerop (forward-line -1))
  3520.               (looking-at "^[ \t]*$")))
  3521.       (c-add-syntax literal (c-point 'bol)))
  3522.      ;; CASE 3: in a cpp preprocessor
  3523.      ((eq literal 'pound)
  3524.       (c-beginning-of-macro lim)
  3525.       (c-add-syntax 'cpp-macro (c-point 'boi)))
  3526.      ;; CASE 4: in an objective-c method intro
  3527.      (in-method-intro-p
  3528.       (c-add-syntax 'objc-method-intro (c-point 'boi)))
  3529.      ;; CASE 5: Line is at top level.
  3530.      ((null containing-sexp)
  3531.       (cond
  3532.        ;; CASE 5A: we are looking at a defun, class, or
  3533.        ;; inline-inclass method opening brace
  3534.        ((= char-after-ip ?{)
  3535.         (cond
  3536.          ;; CASE 5A.1: we are looking at a class opening brace
  3537.          ((save-excursion
  3538.         (goto-char indent-point)
  3539.         (skip-chars-forward " \t{")
  3540.         ;; TBD: watch out! there could be a bogus
  3541.         ;; c-state-cache in place when we get here.  we have
  3542.         ;; to go through much chicanery to ignore the cache.
  3543.         ;; But of course, there may not be!  BLECH!  BOGUS!
  3544.         (let ((decl
  3545.                (if (boundp 'c-state-cache)
  3546.                (let ((old-cache c-state-cache))
  3547.                  (prog2
  3548.                  (makunbound 'c-state-cache)
  3549.                  (c-search-uplist-for-classkey (c-parse-state))
  3550.                    (setq c-state-cache old-cache)))
  3551.              (c-search-uplist-for-classkey (c-parse-state))
  3552.              )))
  3553.           (and decl
  3554.                (setq placeholder (aref decl 0)))
  3555.           ))
  3556.           (c-add-syntax 'class-open placeholder))
  3557.          ;; CASE 5A.2: brace list open
  3558.          ((save-excursion
  3559.         (c-beginning-of-statement-1 lim)
  3560.         ;; c-b-o-s could have left us at point-min
  3561.         (and (bobp)
  3562.              (c-forward-syntactic-ws indent-point))
  3563.         (setq placeholder (point))
  3564.         (and (or (looking-at "enum[ \t\n]+")
  3565.              (= char-before-ip ?=))
  3566.              (save-excursion
  3567.                (skip-chars-forward "^;" indent-point)
  3568.                (/= (following-char) ?\;))))
  3569.           (c-add-syntax 'brace-list-open placeholder))
  3570.          ;; CASE 5A.3: inline defun open
  3571.          (inclass-p
  3572.           (c-add-syntax 'inline-open (aref inclass-p 0)))
  3573.          ;; CASE 5A.4: ordinary defun open
  3574.          (t
  3575.           (goto-char placeholder)
  3576.           (c-add-syntax 'defun-open (c-point 'bol))
  3577.           )))
  3578.        ;; CASE 5B: first K&R arg decl or member init
  3579.        ((c-just-after-func-arglist-p)
  3580.         (cond
  3581.          ;; CASE 5B.1: a member init
  3582.          ((or (= char-before-ip ?:)
  3583.           (= char-after-ip ?:))
  3584.           ;; this line should be indented relative to the beginning
  3585.           ;; of indentation for the topmost-intro line that contains
  3586.           ;; the prototype's open paren
  3587.           ;; TBD: is the following redundant?
  3588.           (if (= char-before-ip ?:)
  3589.           (forward-char -1))
  3590.           (c-backward-syntactic-ws lim)
  3591.           ;; TBD: is the preceding redundant?
  3592.           (if (= (preceding-char) ?:)
  3593.           (progn (forward-char -1)
  3594.              (c-backward-syntactic-ws lim)))
  3595.           (if (= (preceding-char) ?\))
  3596.           (backward-sexp 1))
  3597.           (c-add-syntax 'member-init-intro (c-point 'boi))
  3598.           ;; we don't need to add any class offset since this
  3599.           ;; should be relative to the ctor's indentation
  3600.           )
  3601.          ;; CASE 5B.2: K&R arg decl intro
  3602.          (c-recognize-knr-p
  3603.           (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
  3604.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3605.          ;; CASE 5B.3: nether region after a C++ func decl
  3606.          (t
  3607.           (c-add-syntax 'ansi-funcdecl-cont (c-point 'boi))
  3608.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3609.          ))
  3610.        ;; CASE 5C: inheritance line. could be first inheritance
  3611.        ;; line, or continuation of a multiple inheritance
  3612.        ((or (and c-baseclass-key (looking-at c-baseclass-key))
  3613.         (and (or (= char-before-ip ?:)
  3614.              (= char-after-ip ?:))
  3615.              (save-excursion
  3616.                (c-backward-syntactic-ws lim)
  3617.                (if (= char-before-ip ?:)
  3618.                (progn
  3619.                  (forward-char -1)
  3620.                  (c-backward-syntactic-ws lim)))
  3621.                (back-to-indentation)
  3622.                (looking-at c-class-key))))
  3623.         (cond
  3624.          ;; CASE 5C.1: non-hanging colon on an inher intro
  3625.          ((= char-after-ip ?:)
  3626.           (c-backward-syntactic-ws lim)
  3627.           (c-add-syntax 'inher-intro (c-point 'boi))
  3628.           ;; don't add inclass symbol since relative point already
  3629.           ;; contains any class offset
  3630.           )
  3631.          ;; CASE 5C.2: hanging colon on an inher intro
  3632.          ((= char-before-ip ?:)
  3633.           (c-add-syntax 'inher-intro (c-point 'boi))
  3634.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3635.          ;; CASE 5C.3: a continued inheritance line
  3636.          (t
  3637.           (c-beginning-of-inheritance-list lim)
  3638.           (c-add-syntax 'inher-cont (point))
  3639.           ;; don't add inclass symbol since relative point already
  3640.           ;; contains any class offset
  3641.           )))
  3642.        ;; CASE 5D: this could be a top-level compound statement or a
  3643.        ;; member init list continuation
  3644.        ((= char-before-ip ?,)
  3645.         (goto-char indent-point)
  3646.         (c-backward-syntactic-ws lim)
  3647.         (while (and (< lim (point))
  3648.             (= (preceding-char) ?,))
  3649.           ;; this will catch member inits with multiple
  3650.           ;; line arglists
  3651.           (forward-char -1)
  3652.           (c-backward-syntactic-ws (c-point 'bol))
  3653.           (if (= (preceding-char) ?\))
  3654.           (backward-sexp 1))
  3655.           ;; now continue checking
  3656.           (beginning-of-line)
  3657.           (c-backward-syntactic-ws lim))
  3658.         (cond
  3659.          ;; CASE 5D.1: hanging member init colon, but watch out
  3660.          ;; for bogus matches on access specifiers inside classes.
  3661.          ((and (= (preceding-char) ?:)
  3662.            (save-excursion
  3663.              (forward-word -1)
  3664.              (not (looking-at c-access-key))))
  3665.           (goto-char indent-point)
  3666.           (c-backward-syntactic-ws lim)
  3667.           (c-safe (backward-sexp 1))
  3668.           (c-add-syntax 'member-init-cont (c-point 'boi))
  3669.           ;; we do not need to add class offset since relative
  3670.           ;; point is the member init above us
  3671.           )
  3672.          ;; CASE 5D.2: non-hanging member init colon
  3673.          ((progn
  3674.         (c-forward-syntactic-ws indent-point)
  3675.         (= (following-char) ?:))
  3676.           (skip-chars-forward " \t:")
  3677.           (c-add-syntax 'member-init-cont (point)))
  3678.          ;; CASE 5D.3: perhaps a multiple inheritance line?
  3679.          ((looking-at c-inher-key)
  3680.           (c-add-syntax 'inher-cont (c-point 'boi)))
  3681.          ;; CASE 5D.4: perhaps a template list continuation?
  3682.          ((save-excursion
  3683.         (skip-chars-backward "^<" lim)
  3684.         ;; not sure if this is the right test, but it should
  3685.         ;; be fast and mostly accurate.
  3686.         (and (= (preceding-char) ?<)
  3687.              (not (c-in-literal lim))))
  3688.           ;; we can probably indent it just like and arglist-cont
  3689.           (c-add-syntax 'arglist-cont (point)))
  3690.          ;; CASE 5D.5: perhaps a top-level statement-cont
  3691.          (t
  3692.           (c-beginning-of-statement-1 lim)
  3693.           ;; skip over any access-specifiers
  3694.           (if inclass-p
  3695.           (while (looking-at c-access-key)
  3696.             (forward-line 1)))
  3697.           ;; skip over comments, whitespace
  3698.           (c-forward-syntactic-ws indent-point)
  3699.           (c-add-syntax 'statement-cont (c-point 'boi)))
  3700.          ))
  3701.        ;; CASE 5E: we are looking at a access specifier
  3702.        ((and inclass-p
  3703.          c-access-key
  3704.          (looking-at c-access-key))
  3705.         (c-add-syntax 'access-label (c-point 'bonl))
  3706.         (c-add-syntax 'inclass (aref inclass-p 0)))
  3707.        ;; CASE 5F: we are looking at the brace which closes the
  3708.        ;; enclosing nested class decl
  3709.        ((and inclass-p
  3710.          (= char-after-ip ?})
  3711.          (save-excursion
  3712.            (save-restriction
  3713.              (widen)
  3714.              (forward-char 1)
  3715.              (and
  3716.               (condition-case nil
  3717.               (progn (backward-sexp 1) t)
  3718.             (error nil))
  3719.               (= (point) (aref inclass-p 1))
  3720.               ))))
  3721.         (save-restriction
  3722.           (widen)
  3723.           (goto-char (aref inclass-p 0))
  3724.           (c-add-syntax 'class-close (c-point 'boi))))
  3725.        ;; CASE 5G: we could be looking at subsequent knr-argdecls
  3726.        ((and c-recognize-knr-p
  3727.          (save-excursion
  3728.            (c-backward-syntactic-ws lim)
  3729.            (while (memq (preceding-char) '(?\; ?,))
  3730.              (beginning-of-line)
  3731.              (setq placeholder (point))
  3732.              (c-backward-syntactic-ws lim))
  3733.            (and (= (preceding-char) ?\))
  3734.             (or (not (eq major-mode 'objc-mode))
  3735.                 (progn
  3736.                   (forward-sexp -1)
  3737.                   (forward-char -1)
  3738.                   (c-backward-syntactic-ws)
  3739.                   (not (or (= (preceding-char) ?-)
  3740.                        (= (preceding-char) ?+)
  3741.                        ;; or a class category
  3742.                        (progn
  3743.                      (forward-sexp -2)
  3744.                      (looking-at c-class-key))
  3745.                        )))))
  3746.            )
  3747.          (save-excursion
  3748.            (c-beginning-of-statement-1)
  3749.            (not (looking-at "typedef[ \t\n]+"))))
  3750.         (goto-char placeholder)
  3751.         (c-add-syntax 'knr-argdecl (c-point 'boi)))
  3752.        ;; CASE 5H: we are at the topmost level, make sure we skip
  3753.        ;; back past any access specifiers
  3754.        ((progn
  3755.           (c-backward-syntactic-ws lim)
  3756.           (while (and inclass-p
  3757.               c-access-key
  3758.               (not (bobp))
  3759.               (save-excursion
  3760.                 (c-safe (progn (backward-sexp 1) t))
  3761.                 (looking-at c-access-key)))
  3762.         (backward-sexp 1)
  3763.         (c-backward-syntactic-ws lim))
  3764.           (or (bobp)
  3765.           (memq (preceding-char) '(?\; ?\}))))
  3766.         ;; real beginning-of-line could be narrowed out due to
  3767.         ;; enclosure in a class block
  3768.         (save-restriction
  3769.           (widen)
  3770.           (c-add-syntax 'topmost-intro (c-point 'bol)))
  3771.         (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3772.        ;; CASE 5I: we are at a method definition continuation line
  3773.        ((and (eq major-mode 'objc-mode)
  3774.          (progn
  3775.            (c-beginning-of-statement-1 lim)
  3776.            (beginning-of-line)
  3777.            (looking-at c-ObjC-method-key)))
  3778.         (c-add-syntax 'objc-method-args-cont (point)))
  3779.        ;; CASE 5J: we are at a topmost continuation line
  3780.        (t
  3781.         (c-beginning-of-statement-1 lim)
  3782.         (c-forward-syntactic-ws)
  3783.         (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
  3784.        ))                ; end CASE 5
  3785.      ;; CASE 6: line is an expression, not a statement.  Most
  3786.      ;; likely we are either in a function prototype or a function
  3787.      ;; call argument list
  3788.      ((/= (char-after containing-sexp) ?{)
  3789.       (c-backward-syntactic-ws containing-sexp)
  3790.       (cond
  3791.        ;; CASE 6A: we are looking at the arglist closing paren or
  3792.        ;; at an Objective-C method call closing bracket.
  3793.        ((and (/= char-before-ip ?,)
  3794.          (memq char-after-ip '(?\) ?\])))
  3795.         (if (and (eq major-mode 'objc-mode)
  3796.              (progn
  3797.                (goto-char (1- containing-sexp))
  3798.                (c-backward-syntactic-ws lim)
  3799.                (not (looking-at c-symbol-key))))
  3800.         (c-add-syntax 'statement-cont containing-sexp)
  3801.           (goto-char containing-sexp)
  3802.           (c-add-syntax 'arglist-close (c-point 'boi))))
  3803.        ;; CASE 6B: we are looking at the first argument in an empty
  3804.        ;; argument list. Use arglist-close if we're actually
  3805.        ;; looking at a close paren or bracket.
  3806.        ((memq char-before-ip '(?\( ?\[))
  3807.         (goto-char containing-sexp)
  3808.         (c-add-syntax 'arglist-intro (c-point 'boi)))
  3809.        ;; CASE 6C: we are inside a conditional test clause. treat
  3810.        ;; these things as statements
  3811.        ((save-excursion
  3812.          (goto-char containing-sexp)
  3813.          (and (c-safe (progn (forward-sexp -1) t))
  3814.           (looking-at "\\<for\\>")))
  3815.         (goto-char (1+ containing-sexp))
  3816.         (c-forward-syntactic-ws indent-point)
  3817.         (c-beginning-of-statement-1 containing-sexp)
  3818.         (if (= char-before-ip ?\;)
  3819.         (c-add-syntax 'statement (point))
  3820.           (c-add-syntax 'statement-cont (point))
  3821.           ))
  3822.        ;; CASE 6D: maybe a continued method call. This is the case
  3823.        ;; when we are inside a [] bracketed exp, and what precede
  3824.        ;; the opening bracket is not an identifier.
  3825.        ((and (eq major-mode 'objc-mode)
  3826.          (= (char-after containing-sexp) ?\[)
  3827.          (save-excursion
  3828.            (goto-char (1- containing-sexp))
  3829.            (c-backward-syntactic-ws (c-point 'bod))
  3830.            (if (not (looking-at c-symbol-key))
  3831.                (c-add-syntax 'objc-method-call-cont containing-sexp))
  3832.            )))
  3833.        ;; CASE 6E: we are looking at an arglist continuation line,
  3834.        ;; but the preceding argument is on the same line as the
  3835.        ;; opening paren.  This case includes multi-line
  3836.        ;; mathematical paren groupings, but we could be on a
  3837.        ;; for-list continuation line
  3838.        ((and (save-excursion
  3839.            (goto-char (1+ containing-sexp))
  3840.            (skip-chars-forward " \t")
  3841.            (not (eolp)))
  3842.          (save-excursion
  3843.            (c-beginning-of-statement-1 lim)
  3844.            (skip-chars-backward " \t([")
  3845.            (<= (point) containing-sexp)))
  3846.         (goto-char containing-sexp)
  3847.         (c-add-syntax 'arglist-cont-nonempty (c-point 'boi)))
  3848.        ;; CASE 6F: we are looking at just a normal arglist
  3849.        ;; continuation line
  3850.        (t (c-beginning-of-statement-1 containing-sexp)
  3851.           (forward-char 1)
  3852.           (c-forward-syntactic-ws indent-point)
  3853.           (c-add-syntax 'arglist-cont (c-point 'boi)))
  3854.        ))
  3855.      ;; CASE 7: func-local multi-inheritance line
  3856.      ((and c-baseclass-key
  3857.            (save-excursion
  3858.          (goto-char indent-point)
  3859.          (skip-chars-forward " \t")
  3860.          (looking-at c-baseclass-key)))
  3861.       (goto-char indent-point)
  3862.       (skip-chars-forward " \t")
  3863.       (cond
  3864.        ;; CASE 7A: non-hanging colon on an inher intro
  3865.        ((= char-after-ip ?:)
  3866.         (c-backward-syntactic-ws lim)
  3867.         (c-add-syntax 'inher-intro (c-point 'boi)))
  3868.        ;; CASE 7B: hanging colon on an inher intro
  3869.        ((= char-before-ip ?:)
  3870.         (c-add-syntax 'inher-intro (c-point 'boi)))
  3871.        ;; CASE 7C: a continued inheritance line
  3872.        (t
  3873.         (c-beginning-of-inheritance-list lim)
  3874.         (c-add-syntax 'inher-cont (point))
  3875.         )))
  3876.      ;; CASE 8: we are inside a brace-list
  3877.      ((setq placeholder (c-inside-bracelist-p containing-sexp state))
  3878.       (cond
  3879.        ;; CASE 8A: brace-list-close brace
  3880.        ((and (= char-after-ip ?})
  3881.          (c-safe (progn (forward-char 1)
  3882.                 (backward-sexp 1)
  3883.                 t))
  3884.          (= (point) containing-sexp))
  3885.         (c-add-syntax 'brace-list-close (c-point 'boi)))
  3886.        ;; CASE 8B: we're looking at the first line in a brace-list
  3887.        ((save-excursion
  3888.           (goto-char indent-point)
  3889.           (c-backward-syntactic-ws containing-sexp)
  3890.           (= (point) (1+ containing-sexp)))
  3891.         (goto-char containing-sexp)
  3892.         ;;(if (= char-after-ip ?{)
  3893.         ;;(c-add-syntax 'brace-list-open (c-point 'boi))
  3894.         (c-add-syntax 'brace-list-intro (c-point 'boi))
  3895.         )
  3896.         ;;))            ; end CASE 8B
  3897.        ;; CASE 8C: this is just a later brace-list-entry
  3898.        (t (goto-char (1+ containing-sexp))
  3899.           (c-forward-syntactic-ws indent-point)
  3900.           (if (= char-after-ip ?{)
  3901.           (c-add-syntax 'brace-list-open (point))
  3902.         (c-add-syntax 'brace-list-entry (point))
  3903.         ))            ; end CASE 8C
  3904.        ))                ; end CASE 8
  3905.      ;; CASE 9: A continued statement
  3906.      ((and (not (memq char-before-ip '(?\; ?} ?:)))
  3907.            (> (point)
  3908.           (save-excursion
  3909.             (c-beginning-of-statement-1 containing-sexp)
  3910.             (setq placeholder (point))))
  3911.            (/= placeholder containing-sexp))
  3912.       (goto-char indent-point)
  3913.       (skip-chars-forward " \t")
  3914.       (let ((after-cond-placeholder
  3915.          (save-excursion
  3916.            (goto-char placeholder)
  3917.            (if (looking-at c-conditional-key)
  3918.                (progn
  3919.              (c-safe (c-skip-conditional))
  3920.              (c-forward-syntactic-ws)
  3921.              (if (memq (following-char) '(?\;))
  3922.                  (progn
  3923.                    (forward-char 1)
  3924.                    (c-forward-syntactic-ws)))
  3925.              (point))
  3926.              nil))))
  3927.         (cond
  3928.          ;; CASE 9A: substatement
  3929.          ((and after-cond-placeholder
  3930.            (>= after-cond-placeholder indent-point))
  3931.           (goto-char placeholder)
  3932.           (if (= char-after-ip ?{)
  3933.           (c-add-syntax 'substatement-open (c-point 'boi))
  3934.         (c-add-syntax 'substatement (c-point 'boi))))
  3935.          ;; CASE 9B: open braces for class or brace-lists
  3936.          ((= char-after-ip ?{)
  3937.           (cond
  3938.            ;; CASE 9B.1: class-open
  3939.            ((save-excursion
  3940.           (goto-char indent-point)
  3941.           (skip-chars-forward " \t{")
  3942.           (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3943.             (and decl
  3944.              (setq placeholder (aref decl 0)))
  3945.             ))
  3946.         (c-add-syntax 'class-open placeholder))
  3947.            ;; CASE 9B.2: brace-list-open
  3948.            ((or (save-excursion
  3949.               (goto-char placeholder)
  3950.               (looking-at "\\<enum\\>"))
  3951.             (= char-before-ip ?=))
  3952.         (c-add-syntax 'brace-list-open placeholder))
  3953.            ;; CASE 9B.3: catch-all for unknown construct.
  3954.            (t
  3955.         ;; Even though this isn't right, it's the best I'm
  3956.         ;; going to do for now. Exceptions probably fall
  3957.         ;; through to here, but aren't supported yet.  Also,
  3958.         ;; after the next release, I may call a recognition
  3959.         ;; hook like so: (run-hooks 'c-recognize-hook), but I
  3960.         ;; dunno.
  3961.         (c-add-syntax 'statement-cont placeholder)
  3962.         (c-add-syntax 'block-open))
  3963.            ))
  3964.          ;; CASE 9C: iostream insertion or extraction operator
  3965.          ((looking-at "<<\\|>>")
  3966.           (goto-char placeholder)
  3967.           (and after-cond-placeholder
  3968.            (goto-char after-cond-placeholder))
  3969.           (while (and (re-search-forward "<<\\|>>" indent-point 'move)
  3970.               (c-in-literal placeholder)))
  3971.           ;; if we ended up at indent-point, then the first
  3972.           ;; streamop is on a separate line. Indent the line like
  3973.           ;; a statement-cont instead
  3974.           (if (/= (point) indent-point)
  3975.           (c-add-syntax 'stream-op (c-point 'boi))
  3976.         (c-backward-syntactic-ws lim)
  3977.         (c-add-syntax 'statement-cont (c-point 'boi))))
  3978.          ;; CASE 9D: continued statement. find the accurate
  3979.          ;; beginning of statement or substatement
  3980.          (t
  3981.           (c-beginning-of-statement-1 after-cond-placeholder)
  3982.           ;; KLUDGE ALERT!  c-beginning-of-statement-1 can leave
  3983.           ;; us before the lim we're passing in.  It should be
  3984.           ;; fixed, but I'm worried about side-effects at this
  3985.           ;; late date.  Fix for v5.
  3986.           (goto-char (or (and after-cond-placeholder
  3987.                   (max after-cond-placeholder (point)))
  3988.                  (point)))
  3989.           (c-add-syntax 'statement-cont (point)))
  3990.          )))
  3991.      ;; CASE 10: an else clause?
  3992.      ((looking-at "\\<else\\>[^_]")
  3993.       (c-backward-to-start-of-if containing-sexp)
  3994.       (c-add-syntax 'else-clause (c-point 'boi)))
  3995.      ;; CASE 11: Statement. But what kind?  Lets see if its a
  3996.      ;; while closure of a do/while construct
  3997.      ((progn
  3998.         (goto-char indent-point)
  3999.         (skip-chars-forward " \t")
  4000.         (and (looking-at "while\\b[^_]")
  4001.          (save-excursion
  4002.            (c-backward-to-start-of-do containing-sexp)
  4003.            (setq placeholder (point))
  4004.            (looking-at "do\\b[^_]"))
  4005.          ))
  4006.       (c-add-syntax 'do-while-closure placeholder))
  4007.      ;; CASE 12: A case or default label
  4008.      ((looking-at c-switch-label-key)
  4009.       (goto-char containing-sexp)
  4010.       ;; check for hanging braces
  4011.       (if (/= (point) (c-point 'boi))
  4012.           (forward-sexp -1))
  4013.       (c-add-syntax 'case-label (c-point 'boi)))
  4014.      ;; CASE 13: any other label
  4015.      ((looking-at c-label-key)
  4016.       (goto-char containing-sexp)
  4017.       (c-add-syntax 'label (c-point 'boi)))
  4018.      ;; CASE 14: block close brace, possibly closing the defun or
  4019.      ;; the class
  4020.      ((= char-after-ip ?})
  4021.       (let* ((lim (c-safe-position containing-sexp fullstate))
  4022.          (relpos (save-excursion
  4023.                (goto-char containing-sexp)
  4024.                (if (/= (point) (c-point 'boi))
  4025.                    (c-beginning-of-statement-1 lim))
  4026.                (c-point 'boi))))
  4027.         (cond
  4028.          ;; CASE 14A: does this close an inline?
  4029.          ((progn
  4030.         (goto-char containing-sexp)
  4031.         (c-search-uplist-for-classkey state))
  4032.           (c-add-syntax 'inline-close relpos))
  4033.          ;; CASE 14B: if there an enclosing brace that hasn't
  4034.          ;; been narrowed out by a class, then this is a
  4035.          ;; block-close
  4036.          ((c-most-enclosing-brace state)
  4037.           (c-add-syntax 'block-close relpos))
  4038.          ;; CASE 14C: find out whether we're closing a top-level
  4039.          ;; class or a defun
  4040.          (t
  4041.           (save-restriction
  4042.         (narrow-to-region (point-min) indent-point)
  4043.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  4044.           (if decl
  4045.               (c-add-syntax 'class-close (aref decl 0))
  4046.             (c-add-syntax 'defun-close relpos)))))
  4047.          )))
  4048.      ;; CASE 15: statement catchall
  4049.      (t
  4050.       ;; we know its a statement, but we need to find out if it is
  4051.       ;; the first statement in a block
  4052.       (goto-char containing-sexp)
  4053.       (forward-char 1)
  4054.       (c-forward-syntactic-ws indent-point)
  4055.       ;; now skip forward past any case/default clauses we might find.
  4056.       (while (or (c-skip-case-statement-forward fullstate indent-point)
  4057.              (and (looking-at c-switch-label-key)
  4058.               (not inswitch-p)))
  4059.         (setq inswitch-p t))
  4060.       ;; we want to ignore non-case labels when skipping forward
  4061.       (while (and (looking-at c-label-key)
  4062.               (goto-char (match-end 0)))
  4063.         (c-forward-syntactic-ws indent-point))
  4064.       (cond
  4065.        ;; CASE 15A: we are inside a case/default clause inside a
  4066.        ;; switch statement.  find out if we are at the statement
  4067.        ;; just after the case/default label.
  4068.        ((and inswitch-p
  4069.          (progn
  4070.            (goto-char indent-point)
  4071.            (c-backward-syntactic-ws containing-sexp)
  4072.            (back-to-indentation)
  4073.            (setq placeholder (point))
  4074.            (looking-at c-switch-label-key)))
  4075.         (goto-char indent-point)
  4076.         (skip-chars-forward " \t")
  4077.         (if (= (following-char) ?{)
  4078.         (c-add-syntax 'statement-case-open placeholder)
  4079.           (c-add-syntax 'statement-case-intro placeholder)))
  4080.        ;; CASE 15B: continued statement
  4081.        ((= char-before-ip ?,)
  4082.         (c-add-syntax 'statement-cont (c-point 'boi)))
  4083.        ;; CASE 15C: a question/colon construct?  But make sure
  4084.        ;; what came before was not a label, and what comes after
  4085.        ;; is not a globally scoped function call!
  4086.        ((or (and (memq char-before-ip '(?: ??))
  4087.              (save-excursion
  4088.                (goto-char indent-point)
  4089.                (c-backward-syntactic-ws lim)
  4090.                (back-to-indentation)
  4091.                (not (looking-at c-label-key))))
  4092.         (and (memq char-after-ip '(?: ??))
  4093.              (save-excursion
  4094.                (goto-char indent-point)
  4095.                (skip-chars-forward " \t")
  4096.                ;; watch out for scope operator
  4097.                (not (looking-at "::")))))
  4098.         (c-add-syntax 'statement-cont (c-point 'boi)))
  4099.        ;; CASE 15D: any old statement
  4100.        ((< (point) indent-point)
  4101.         (let ((safepos (c-most-enclosing-brace fullstate)))
  4102.           (goto-char indent-point)
  4103.           (c-beginning-of-statement-1 safepos)
  4104.           (c-add-syntax 'statement (c-point 'boi))
  4105.           (if (= char-after-ip ?{)
  4106.           (c-add-syntax 'block-open))))
  4107.        ;; CASE 15E: first statement in an inline, or first
  4108.        ;; statement in a top-level defun. we can tell this is it
  4109.        ;; if there are no enclosing braces that haven't been
  4110.        ;; narrowed out by a class (i.e. don't use bod here!)
  4111.        ((save-excursion
  4112.           (save-restriction
  4113.         (widen)
  4114.         (goto-char containing-sexp)
  4115.         (c-narrow-out-enclosing-class state containing-sexp)
  4116.         (not (c-most-enclosing-brace state))))
  4117.         (goto-char containing-sexp)
  4118.         ;; if not at boi, then defun-opening braces are hung on
  4119.         ;; right side, so we need a different relpos
  4120.         (if (/= (point) (c-point 'boi))
  4121.         (progn
  4122.           (c-backward-syntactic-ws)
  4123.           (c-safe (forward-sexp (if (= (preceding-char) ?\))
  4124.                         -1 -2)))
  4125.           ))
  4126.         (c-add-syntax 'defun-block-intro (c-point 'boi)))
  4127.        ;; CASE 15F: first statement in a block
  4128.        (t (goto-char containing-sexp)
  4129.           (if (/= (point) (c-point 'boi))
  4130.           (c-beginning-of-statement-1
  4131.            (if (= (point) lim)
  4132.                (c-safe-position (point) state) lim)))
  4133.           (c-add-syntax 'statement-block-intro (c-point 'boi))
  4134.           (if (= char-after-ip ?{)
  4135.           (c-add-syntax 'block-open)))
  4136.        ))
  4137.      )
  4138.  
  4139.     ;; now we need to look at any modifiers
  4140.     (goto-char indent-point)
  4141.     (skip-chars-forward " \t")
  4142.     ;; are we looking at a comment only line?
  4143.     (if (looking-at c-comment-start-regexp)
  4144.         (c-add-syntax 'comment-intro))
  4145.     ;; we might want to give additional offset to friends (in C++).
  4146.     (if (and (eq major-mode 'c++-mode)
  4147.          (looking-at c-C++-friend-key))
  4148.         (c-add-syntax 'friend))
  4149.     ;; return the syntax
  4150.     syntax))))
  4151.  
  4152.  
  4153. ;; indent via syntactic language elements
  4154. (defun c-get-offset (langelem)
  4155.   ;; Get offset from LANGELEM which is a cons cell of the form:
  4156.   ;; (SYMBOL . RELPOS).  The symbol is matched against
  4157.   ;; c-offsets-alist and the offset found there is either returned,
  4158.   ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
  4159.   ;; the offset is simply returned.
  4160.   (let* ((symbol (car langelem))
  4161.      (relpos (cdr langelem))
  4162.      (match  (assq symbol c-offsets-alist))
  4163.      (offset (cdr-safe match)))
  4164.     ;; offset can be a number, a function, a variable, or one of the
  4165.     ;; symbols + or -
  4166.     (cond
  4167.      ((not match)
  4168.       (if c-strict-syntax-p
  4169.       (error "don't know how to indent a %s" symbol)
  4170.     (setq offset 0
  4171.           relpos 0)))
  4172.      ((eq offset '+)  (setq offset c-basic-offset))
  4173.      ((eq offset '-)  (setq offset (- c-basic-offset)))
  4174.      ((eq offset '++) (setq offset (* 2 c-basic-offset)))
  4175.      ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
  4176.      ((eq offset '*)  (setq offset (/ c-basic-offset 2)))
  4177.      ((eq offset '/)  (setq offset (/ (- c-basic-offset) 2)))
  4178.      ((and (not (numberp offset))
  4179.        (fboundp offset))
  4180.       (setq offset (funcall offset langelem)))
  4181.      ((not (numberp offset))
  4182.       (setq offset (eval offset)))
  4183.      )
  4184.     (+ (if (and relpos
  4185.         (< relpos (c-point 'bol)))
  4186.        (save-excursion
  4187.          (goto-char relpos)
  4188.          (current-column))
  4189.      0)
  4190.        offset)))
  4191.  
  4192. (defun c-indent-line (&optional syntax)
  4193.   ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the
  4194.   ;; syntactic information for the current line. Returns the amount of
  4195.   ;; indentation change
  4196.   (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
  4197.      (pos (- (point-max) (point)))
  4198.      (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))
  4199.      (shift-amt  (- (current-indentation) indent)))
  4200.     (and c-echo-syntactic-information-p
  4201.      (message "syntax: %s, indent= %d" c-syntactic-context indent))
  4202.     (if (zerop shift-amt)
  4203.     nil
  4204.       (delete-region (c-point 'bol) (c-point 'boi))
  4205.       (beginning-of-line)
  4206.       (indent-to indent))
  4207.     (if (< (point) (c-point 'boi))
  4208.     (back-to-indentation)
  4209.       ;; If initial point was within line's indentation, position after
  4210.       ;; the indentation.  Else stay at same point in text.
  4211.       (if (> (- (point-max) pos) (point))
  4212.       (goto-char (- (point-max) pos)))
  4213.       )
  4214.     (run-hooks 'c-special-indent-hook)
  4215.     shift-amt))
  4216.  
  4217. (defun c-show-syntactic-information ()
  4218.   "Show syntactic information for current line."
  4219.   (interactive)
  4220.   (message "syntactic analysis: %s" (c-guess-basic-syntax))
  4221.   (c-keep-region-active))
  4222.  
  4223.  
  4224. ;; Standard indentation line-ups
  4225. (defun c-lineup-arglist (langelem)
  4226.   ;; lineup the current arglist line with the arglist appearing just
  4227.   ;; after the containing paren which starts the arglist.
  4228.   (save-excursion
  4229.     (let* ((containing-sexp
  4230.         (save-excursion
  4231.           ;; arglist-cont-nonempty gives relpos ==
  4232.           ;; to boi of containing-sexp paren. This
  4233.           ;; is good when offset is +, but bad
  4234.           ;; when it is c-lineup-arglist, so we
  4235.           ;; have to special case a kludge here.
  4236.           (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
  4237.           (progn
  4238.             (beginning-of-line)
  4239.             (backward-up-list 1)
  4240.             (skip-chars-forward " \t" (c-point 'eol)))
  4241.         (goto-char (cdr langelem)))
  4242.           (point)))
  4243.        (cs-curcol (save-excursion
  4244.             (goto-char (cdr langelem))
  4245.             (current-column))))
  4246.       (if (save-excursion
  4247.         (beginning-of-line)
  4248.         (looking-at "[ \t]*)"))
  4249.       (progn (goto-char (match-end 0))
  4250.          (forward-sexp -1)
  4251.          (forward-char 1)
  4252.          (c-forward-syntactic-ws)
  4253.          (- (current-column) cs-curcol))
  4254.     (goto-char containing-sexp)
  4255.     (or (eolp)
  4256.         (not (memq (following-char) '(?{ ?\( )))
  4257.         (let ((eol (c-point 'eol))
  4258.           (here (progn
  4259.               (forward-char 1)
  4260.               (skip-chars-forward " \t")
  4261.               (point))))
  4262.           (c-forward-syntactic-ws)
  4263.           (if (< (point) eol)
  4264.           (goto-char here))))
  4265.     (- (current-column) cs-curcol)
  4266.     ))))
  4267.  
  4268. (defun c-lineup-arglist-intro-after-paren (langelem)
  4269.   ;; lineup an arglist-intro line to just after the open paren
  4270.   (save-excursion
  4271.     (let ((cs-curcol (save-excursion
  4272.                (goto-char (cdr langelem))
  4273.                (current-column)))
  4274.       (ce-curcol (save-excursion
  4275.                (beginning-of-line)
  4276.                (backward-up-list 1)
  4277.                (skip-chars-forward " \t" (c-point 'eol))
  4278.                (current-column))))
  4279.       (- ce-curcol cs-curcol -1))))
  4280.  
  4281. (defun c-lineup-streamop (langelem)
  4282.   ;; lineup stream operators
  4283.   (save-excursion
  4284.     (let* ((relpos (cdr langelem))
  4285.        (curcol (progn (goto-char relpos)
  4286.               (current-column))))
  4287.       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
  4288.       (goto-char (match-beginning 0))
  4289.       (- (current-column) curcol))))
  4290.  
  4291. (defun c-lineup-multi-inher (langelem)
  4292.   ;; line up multiple inheritance lines
  4293.   (save-excursion
  4294.     (let (cs-curcol
  4295.       (eol (c-point 'eol))
  4296.       (here (point)))
  4297.       (goto-char (cdr langelem))
  4298.       (setq cs-curcol (current-column))
  4299.       (skip-chars-forward "^:" eol)
  4300.       (skip-chars-forward " \t:" eol)
  4301.       (if (or (eolp)
  4302.           (looking-at c-comment-start-regexp))
  4303.       (c-forward-syntactic-ws here))
  4304.       (- (current-column) cs-curcol)
  4305.       )))
  4306.  
  4307. (defun c-lineup-C-comments (langelem)
  4308.   ;; line up C block comment continuation lines
  4309.   (save-excursion
  4310.     (let ((stars (progn
  4311.            (beginning-of-line)
  4312.            (skip-chars-forward " \t")
  4313.            (if (looking-at "\\*\\*?")
  4314.                (- (match-end 0) (match-beginning 0))
  4315.              0)))
  4316.       (cs-curcol (progn (goto-char (cdr langelem))
  4317.                 (current-column))))
  4318.       (back-to-indentation)
  4319.       (if (re-search-forward "/\\*[ \t]*" (c-point 'eol) t)
  4320.       (goto-char (+ (match-beginning 0)
  4321.             (cond
  4322.              (c-block-comments-indent-p 0)
  4323.              ((= stars 1) 1)
  4324.              ((= stars 2) 0)
  4325.              (t (- (match-end 0) (match-beginning 0)))))))
  4326.       (- (current-column) cs-curcol))))
  4327.  
  4328. (defun c-lineup-comment (langelem)
  4329.   ;; support old behavior for comment indentation. we look at
  4330.   ;; c-comment-only-line-offset to decide how to indent comment
  4331.   ;; only-lines
  4332.   (save-excursion
  4333.     (back-to-indentation)
  4334.     ;; indent as specified by c-comment-only-line-offset
  4335.     (if (not (bolp))
  4336.     (or (car-safe c-comment-only-line-offset)
  4337.         c-comment-only-line-offset)
  4338.       (or (cdr-safe c-comment-only-line-offset)
  4339.       (car-safe c-comment-only-line-offset)
  4340.       -1000                ;jam it against the left side
  4341.       ))))
  4342.  
  4343. (defun c-lineup-runin-statements (langelem)
  4344.   ;; line up statements in coding standards which place the first
  4345.   ;; statement on the same line as the block opening brace.
  4346.   (if (= (char-after (cdr langelem)) ?{)
  4347.       (save-excursion
  4348.     (let ((curcol (progn
  4349.             (goto-char (cdr langelem))
  4350.             (current-column))))
  4351.       (forward-char 1)
  4352.       (skip-chars-forward " \t")
  4353.       (- (current-column) curcol)))
  4354.     0))
  4355.  
  4356. (defun c-lineup-math (langelem)
  4357.   ;; line up math statement-cont after the equals
  4358.   (save-excursion
  4359.     (let* ((relpos (cdr langelem))
  4360.        (equalp (save-excursion
  4361.              (goto-char (c-point 'boi))
  4362.              (skip-chars-forward "^=" (c-point 'eol))
  4363.              (and (= (following-char) ?=)
  4364.               (- (point) (c-point 'boi)))))
  4365.        (curcol (progn
  4366.              (goto-char relpos)
  4367.              (current-column)))
  4368.        donep)
  4369.       (while (and (not donep)
  4370.           (< (point) (c-point 'eol)))
  4371.     (skip-chars-forward "^=" (c-point 'eol))
  4372.     (if (c-in-literal (cdr langelem))
  4373.         (forward-char 1)
  4374.       (setq donep t)))
  4375.       (if (/= (following-char) ?=)
  4376.       ;; there's no equal sign on the line
  4377.       c-basic-offset
  4378.     ;; calculate indentation column after equals and ws, unless
  4379.     ;; our line contains an equals sign
  4380.     (if (not equalp)
  4381.         (progn
  4382.           (forward-char 1)
  4383.           (skip-chars-forward " \t")
  4384.           (setq equalp 0)))
  4385.     (- (current-column) equalp curcol))
  4386.       )))
  4387.  
  4388. (defun c-lineup-ObjC-method-call (langelem)
  4389.   ;; Line up methods args as elisp-mode does with function args: go to
  4390.   ;; the position right after the message receiver, and if you are at
  4391.   ;; (eolp) indent the current line by a constant offset from the
  4392.   ;; opening bracket; otherwise we are looking at the first character
  4393.   ;; of the first method call argument, so lineup the current line
  4394.   ;; with it.
  4395.   (save-excursion
  4396.     (let* ((extra (save-excursion
  4397.             (back-to-indentation)
  4398.             (c-backward-syntactic-ws (cdr langelem))
  4399.             (if (= (preceding-char) ?:)
  4400.             (- c-basic-offset)
  4401.               0)))
  4402.        (open-bracket-pos (cdr langelem))
  4403.            (open-bracket-col (progn
  4404.                    (goto-char open-bracket-pos)
  4405.                    (current-column)))
  4406.            (target-col (progn
  4407.              (forward-char)
  4408.              (forward-sexp)
  4409.              (skip-chars-forward " \t")
  4410.              (if (eolp)
  4411.                  (+ open-bracket-col c-basic-offset)
  4412.                (current-column))))
  4413.        )
  4414.       (- target-col open-bracket-col extra))))
  4415.  
  4416. (defun c-lineup-ObjC-method-args (langelem)
  4417.   ;; Line up the colons that separate args. This is done trying to
  4418.   ;; align colons vertically.
  4419.   (save-excursion
  4420.     (let* ((here (c-point 'boi))
  4421.        (curcol (progn (goto-char here) (current-column)))
  4422.        (eol (c-point 'eol))
  4423.        (relpos (cdr langelem))
  4424.        (first-col-column (progn
  4425.                    (goto-char relpos)
  4426.                    (skip-chars-forward "^:" eol)
  4427.                    (and (= (following-char) ?:)
  4428.                     (current-column)))))
  4429.       (if (not first-col-column)
  4430.       c-basic-offset
  4431.     (goto-char here)
  4432.     (skip-chars-forward "^:" eol)
  4433.     (if (= (following-char) ?:)
  4434.         (+ curcol (- first-col-column (current-column)))
  4435.       c-basic-offset)))))
  4436.  
  4437. (defun c-lineup-ObjC-method-args-2 (langelem)
  4438.   ;; Line up the colons that separate args. This is done trying to
  4439.   ;; align the colon on the current line with the previous one.
  4440.   (save-excursion
  4441.     (let* ((here (c-point 'boi))
  4442.        (curcol (progn (goto-char here) (current-column)))
  4443.        (eol (c-point 'eol))
  4444.        (relpos (cdr langelem))
  4445.        (prev-col-column (progn
  4446.                   (skip-chars-backward "^:" relpos)
  4447.                   (and (= (preceding-char) ?:)
  4448.                    (- (current-column) 1)))))
  4449.       (if (not prev-col-column)
  4450.       c-basic-offset
  4451.     (goto-char here)
  4452.     (skip-chars-forward "^:" eol)
  4453.     (if (= (following-char) ?:)
  4454.         (+ curcol (- prev-col-column (current-column)))
  4455.       c-basic-offset)))))
  4456.  
  4457. (defun c-snug-do-while (syntax pos)
  4458.   "Dynamically calculate brace hanginess for do-while statements.
  4459. Using this function, `while' clauses that end a `do-while' block will
  4460. remain on the same line as the brace that closes that block.
  4461.  
  4462. See `c-hanging-braces-alist' for how to utilize this function as an
  4463. ACTION associated with `block-close' syntax."
  4464.   (save-excursion
  4465.     (let (langelem)
  4466.       (if (and (eq syntax 'block-close)
  4467.            (setq langelem (assq 'block-close c-syntactic-context))
  4468.            (progn (goto-char (cdr langelem))
  4469.               (if (= (following-char) ?{)
  4470.               (c-safe (forward-sexp -1)))
  4471.               (looking-at "\\<do\\>[^_]")))
  4472.       '(before)
  4473.     '(before after)))))
  4474.  
  4475.  
  4476. ;;; This page handles insertion and removal of backslashes for C macros.
  4477.  
  4478. (defun c-backslash-region (from to delete-flag)
  4479.   "Insert, align, or delete end-of-line backslashes on the lines in the region.
  4480. With no argument, inserts backslashes and aligns existing backslashes.
  4481. With an argument, deletes the backslashes.
  4482.  
  4483. This function does not modify the last line of the region if the region ends 
  4484. right at the start of the following line; it does not modify blank lines
  4485. at the start of the region.  So you can put the region around an entire macro
  4486. definition and conveniently use this command."
  4487.   (interactive "r\nP")
  4488.   (save-excursion
  4489.     (goto-char from)
  4490.     (let ((column c-backslash-column)
  4491.           (endmark (make-marker)))
  4492.       (move-marker endmark to)
  4493.       ;; Compute the smallest column number past the ends of all the lines.
  4494.       (if (not delete-flag)
  4495.           (while (< (point) to)
  4496.             (end-of-line)
  4497.             (if (= (preceding-char) ?\\)
  4498.                 (progn (forward-char -1)
  4499.                        (skip-chars-backward " \t")))
  4500.             (setq column (max column (1+ (current-column))))
  4501.             (forward-line 1)))
  4502.       ;; Adjust upward to a tab column, if that doesn't push past the margin.
  4503.       (if (> (% column tab-width) 0)
  4504.           (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
  4505.             (if (< adjusted (window-width))
  4506.                 (setq column adjusted))))
  4507.       ;; Don't modify blank lines at start of region.
  4508.       (goto-char from)
  4509.       (while (and (< (point) endmark) (eolp))
  4510.         (forward-line 1))
  4511.       ;; Add or remove backslashes on all the lines.
  4512.       (while (and (< (point) endmark)
  4513.                   ;; Don't backslashify the last line
  4514.                   ;; if the region ends right at the start of the next line.
  4515.                   (save-excursion
  4516.                     (forward-line 1)
  4517.                     (< (point) endmark)))
  4518.         (if (not delete-flag)
  4519.             (c-append-backslash column)
  4520.           (c-delete-backslash))
  4521.         (forward-line 1))
  4522.       (move-marker endmark nil))))
  4523.  
  4524. (defun c-append-backslash (column)
  4525.   (end-of-line)
  4526.   ;; Note that "\\\\" is needed to get one backslash.
  4527.   (if (= (preceding-char) ?\\)
  4528.       (progn (forward-char -1)
  4529.              (delete-horizontal-space)
  4530.              (indent-to column))
  4531.     (indent-to column)
  4532.     (insert "\\")))
  4533.  
  4534. (defun c-delete-backslash ()
  4535.   (end-of-line)
  4536.   (forward-char -1)
  4537.   (if (looking-at "\\\\")
  4538.       (delete-region (1+ (point))
  4539.                      (progn (skip-chars-backward " \t") (point)))))
  4540.  
  4541.  
  4542. ;; defuns for submitting bug reports
  4543.  
  4544. (defconst c-version "4.241"
  4545.   "cc-mode version number.")
  4546. (defconst c-mode-help-address "cc-mode-help@merlin.cnri.reston.va.us"
  4547.   "Address accepting submission of bug reports.")
  4548.  
  4549. (defun c-version ()
  4550.   "Echo the current version of cc-mode in the minibuffer."
  4551.   (interactive)
  4552.   (message "Using cc-mode version %s" c-version)
  4553.   (c-keep-region-active))
  4554.  
  4555. ;; get reporter-submit-bug-report when byte-compiling
  4556. (eval-when-compile
  4557.   (require 'reporter))
  4558.  
  4559. (defun c-submit-bug-report ()
  4560.   "Submit via mail a bug report on cc-mode."
  4561.   (interactive)
  4562.   ;; load in reporter
  4563.   (let ((reporter-prompt-for-summary-p t)
  4564.     (reporter-dont-compact-list '(c-offsets-alist)))
  4565.     (and
  4566.      (if (y-or-n-p "Do you want to submit a report on cc-mode? ")
  4567.      t (message "") nil)
  4568.      (require 'reporter)
  4569.      (reporter-submit-bug-report
  4570.       c-mode-help-address
  4571.       (concat "cc-mode " c-version " ("
  4572.           (cond ((eq major-mode 'c++-mode)  "C++")
  4573.             ((eq major-mode 'c-mode)    "C")
  4574.             ((eq major-mode 'objc-mode) "ObjC"))
  4575.           ")")
  4576.       (let ((vars (list
  4577.            ;; report only the vars that affect indentation
  4578.            'c-basic-offset
  4579.            'c-offsets-alist
  4580.            'c-block-comments-indent-p
  4581.            'c-cleanup-list
  4582.            'c-comment-only-line-offset
  4583.            'c-backslash-column
  4584.            'c-delete-function
  4585.            'c-electric-pound-behavior
  4586.            'c-hanging-braces-alist
  4587.            'c-hanging-colons-alist
  4588.            'c-hanging-comment-ender-p
  4589.            'c-tab-always-indent
  4590.            'c-recognize-knr-p
  4591.            'defun-prompt-regexp
  4592.            'tab-width
  4593.            )))
  4594.     (if (not (boundp 'defun-prompt-regexp))
  4595.         (delq 'defun-prompt-regexp vars)
  4596.       vars))
  4597.       (function
  4598.        (lambda ()
  4599.      (insert
  4600.       (if c-special-indent-hook
  4601.           (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  4602.               "c-special-indent-hook is set to '"
  4603.               (format "%s" c-special-indent-hook)
  4604.               ".\nPerhaps this is your problem?\n"
  4605.               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
  4606.         "\n")
  4607.       (format "c-emacs-features: %s\n" c-emacs-features)
  4608.       )))
  4609.       nil
  4610.       "Dear Barry,"
  4611.       ))))
  4612.  
  4613.  
  4614. ;; menus for XEmacs (formerly Lucid)
  4615. (defun c-popup-menu (e)
  4616.   "Pops up the C/C++/ObjC menu."
  4617.   (interactive "@e")
  4618.   (popup-menu (cons (concat mode-name " Mode Commands") c-mode-menu))
  4619.   (c-keep-region-active))
  4620.     
  4621.  
  4622. (defun c-copy-tree (tree)
  4623.   ;; Line XEmacs 19.12's copy-tree
  4624.   (if (consp tree)
  4625.       (cons (c-copy-tree (car tree))
  4626.         (c-copy-tree (cdr tree)))
  4627.     (if (vectorp tree)
  4628.     (let* ((new (copy-sequence tree))
  4629.            (i (1- (length new))))
  4630.       (while (>= i 0)
  4631.         (aset new i (c-copy-tree (aref new i)))
  4632.         (setq i (1- i)))
  4633.       new)
  4634.       tree)))
  4635.  
  4636. (defun c-mapcar-defun (var)
  4637.   (let ((val (symbol-value var)))
  4638.     (cons var (if (atom val) val
  4639.         ;; XEmacs 19.12 and Emacs 19 + lucid.el have this
  4640.         (if (fboundp 'copy-tree)
  4641.             (copy-tree val)
  4642.           ;; Emacs 19 and Emacs 18
  4643.           (c-copy-tree val)
  4644.           )))
  4645.     ))
  4646.  
  4647. ;; dynamically append the default value of most variables. This is
  4648. ;; crucial because future c-set-style calls will always reset the
  4649. ;; variables first to the "CC-MODE" style before instituting the new
  4650. ;; style.  Only do this once!
  4651. (or (assoc "CC-MODE" c-style-alist)
  4652.     (progn
  4653.       (c-add-style "CC-MODE"
  4654.            (mapcar 'c-mapcar-defun
  4655.                '(c-backslash-column
  4656.                  c-basic-offset
  4657.                  c-block-comments-indent-p
  4658.                  c-cleanup-list
  4659.                  c-comment-only-line-offset
  4660.                  c-echo-syntactic-information-p
  4661.                  c-electric-pound-behavior
  4662.                  c-hanging-braces-alist
  4663.                  c-hanging-colons-alist
  4664.                  c-hanging-comment-ender-p
  4665.                  c-offsets-alist
  4666.                  c-recognize-knr-p
  4667.                  c-strict-syntax-p
  4668.                  c-tab-always-indent
  4669.                  c-inhibit-startup-warnings-p
  4670.                  ))))
  4671.     ;; the default style is now GNU.  This can be overridden in
  4672.     ;; c-mode-common-hook or {c,c++,objc}-mode-hook.
  4673.     (c-set-style "GNU"))
  4674.  
  4675. ;; style variables
  4676. (make-variable-buffer-local 'c-offsets-alist)
  4677. (make-variable-buffer-local 'c-basic-offset)
  4678. (make-variable-buffer-local 'c-file-style)
  4679. (make-variable-buffer-local 'c-file-offsets)
  4680. (make-variable-buffer-local 'c-comment-only-line-offset)
  4681. (make-variable-buffer-local 'c-block-comments-indent-p)
  4682. (make-variable-buffer-local 'c-cleanup-list)
  4683. (make-variable-buffer-local 'c-hanging-braces-alist)
  4684. (make-variable-buffer-local 'c-hanging-colons-alist)
  4685. (make-variable-buffer-local 'c-hanging-comment-ender-p)
  4686. (make-variable-buffer-local 'c-backslash-column)
  4687.  
  4688.  
  4689.  
  4690. ;; fsets for compatibility with BOCM
  4691. (fset 'electric-c-brace      'c-electric-brace)
  4692. (fset 'electric-c-semi       'c-electric-semi&comma)
  4693. (fset 'electric-c-sharp-sign 'c-electric-pound)
  4694. ;; there is no cc-mode equivalent for electric-c-terminator
  4695. (fset 'mark-c-function       'c-mark-function)
  4696. (fset 'indent-c-exp          'c-indent-exp)
  4697. (fset 'set-c-style           'c-set-style)
  4698. ;; lemacs 19.9 + font-lock + cc-mode - c++-mode lossage
  4699. (fset 'c++-beginning-of-defun 'beginning-of-defun)
  4700. (fset 'c++-end-of-defun 'end-of-defun)
  4701.  
  4702. ;; set up bc warnings for obsolete variables, but for now lets not
  4703. ;; worry about obsolete functions.  maybe later some will be important
  4704. ;; to flag
  4705. (and (memq 'v19 c-emacs-features)
  4706.      (let* ((na "Nothing appropriate.")
  4707.         (vars
  4708.          (list
  4709.           (cons 'c++-c-mode-syntax-table 'c-mode-syntaxt-table)
  4710.           (cons 'c++-tab-always-indent 'c-tab-always-indent)
  4711.           (cons 'c++-always-arglist-indent-p na)
  4712.           (cons 'c++-block-close-brace-offset 'c-offsets-alist)
  4713.           (cons 'c++-paren-as-block-close-p na)
  4714.           (cons 'c++-continued-member-init-offset 'c-offsets-alist)
  4715.           (cons 'c++-member-init-indent 'c-offsets-alist)
  4716.           (cons 'c++-friend-offset na)
  4717.           (cons 'c++-access-specifier-offset 'c-offsets-alist)
  4718.           (cons 'c++-empty-arglist-indent 'c-offsets-alist)
  4719.           (cons 'c++-comment-only-line-offset 'c-comment-only-line-offset)
  4720.           (cons 'c++-C-block-comments-indent-p 'c-block-comments-indent-p)
  4721.           (cons 'c++-cleanup-list 'c-cleanup-list)
  4722.           (cons 'c++-hanging-braces 'c-hanging-braces-alist)
  4723.           (cons 'c++-hanging-member-init-colon 'c-hanging-colons-alist)
  4724.           (cons 'c++-auto-hungry-initial-state
  4725.             "Use `c-auto-newline' and `c-hungry-delete-key' instead.")
  4726.           (cons 'c++-auto-hungry-toggle na)
  4727.           (cons 'c++-relative-offset-p na)
  4728.           (cons 'c++-special-indent-hook 'c-special-indent-hook)
  4729.           (cons 'c++-delete-function 'c-delete-function)
  4730.           (cons 'c++-electric-pound-behavior 'c-electric-pound-behavior)
  4731.           (cons 'c++-hungry-delete-key 'c-hungry-delete-key)
  4732.           (cons 'c++-auto-newline 'c-auto-newline)
  4733.           (cons 'c++-match-header-strongly na)
  4734.           (cons 'c++-defun-header-strong-struct-equivs na)
  4735.           (cons 'c++-version 'c-version)
  4736.           (cons 'c++-mode-help-address 'c-mode-help-address)
  4737.           (cons 'c-indent-level 'c-basic-offset)
  4738.           (cons 'c-brace-imaginary-offset na)
  4739.           (cons 'c-brace-offset 'c-offsets-alist)
  4740.           (cons 'c-argdecl-indent 'c-offsets-alist)
  4741.           (cons 'c-label-offset 'c-offsets-alist)
  4742.           (cons 'c-continued-statement-offset 'c-offsets-alist)
  4743.           (cons 'c-continued-brace-offset 'c-offsets-alist)
  4744.           (cons 'c-default-macroize-column 'c-backslash-column)
  4745.           (cons 'c++-default-macroize-column 'c-backslash-column)
  4746.           )))
  4747.        (mapcar
  4748.     (function
  4749.      (lambda (elt)
  4750.        (make-obsolete-variable (car elt) (cdr elt))))
  4751.     vars)))
  4752.  
  4753. (provide 'cc-mode)
  4754. ;;; cc-mode.el ends here
  4755.